靶場簡介
upload-labs是一個專門用于學習文件上傳漏洞攻擊和防御的靶場。它提供了一系列模擬文件上傳漏洞的實驗環(huán)境,用于幫助用戶了解文件上傳漏洞的原理和防御技術。
這個靶場包括了常見的文件上傳漏洞類型,如文件名欺騙、文件類型欺騙、文件上傳功能繞過等。通過練習不同的攻擊方式,用戶可以加深對文件上傳漏洞的理解和提高對這類漏洞的攻擊和防御技能
靶場搭建
upload-labs靶場下載地址:https://github.com/c0ny1/upload-labs
將下載好的upload-labs解壓至phpstudy的WWW目錄,隨后開啟phpstudy
靶場通關
pass-1(JS代碼繞過)
源碼審計
查看網(wǎng)頁HTML源碼, 可以發(fā)現(xiàn)此關卡是通過JS代碼來驗證上傳文件的類型, 只要將JS代碼禁止掉就能繞過上傳限制
演示步驟
準備一個webshell.php腳本文件, 文件內容如下所示, 是一個簡單的一句話木馬
<?php @eval($_POST[123]);?>
將腳本文件上傳, 結果直接被網(wǎng)站攔截掉了
網(wǎng)頁欄輸入about:config
, 搜索javascript, 將javascript.enabled的
值設置為false
, 即表示瀏覽器禁止執(zhí)行javascript代碼
刷新第一關卡頁面, 再次上傳webshell.php, 鼠標右鍵查看該圖像的地址, 即為webshell的網(wǎng)頁路徑. 例如此處我上傳的webshell路徑為http://www.upload-labs.net:81/upload/webshell.php
打開蟻劍, 輸入webshell的路徑和密碼, 然后點擊測試連接, 顯示連接成功
pass-2(MIME類型繞過)
源碼審計
此關卡是通過對上傳的文件類型進行檢驗, 若文件類型不為image/jpeg
, 則上傳失敗, 只需抓包修改Content-type字段的值為image/jpeg
即可繞過限制
演示步驟
使用burpsuite抓取上傳webshell.php的數(shù)據(jù)包, 將Content-Type字段的值修改成image/jpeg
文件上傳成功, 后面操作就不演示了
pass-3(上傳可解析后綴)
源碼審計
此關卡的黑名單只有asp、aspx、php、jsp, 并沒有限制php3, php5這些后綴
演示步驟
首先, 我們需要在phpstudy的http.conf文件添加如下一行, 目的是為了讓網(wǎng)站能夠解析后綴為php5文件, 然后重啟phpstudy
AddType application/x-httpd-php .php .phtml .php5
上傳webshell.php5文件, 文件內容如下所示:
<?php phpinfo();?>
文件上傳成功后, 鼠標右鍵復制下面的圖片路徑, 該路徑即為上傳的webshell, 可以發(fā)現(xiàn)網(wǎng)站是能夠解析php5文件的
pass-4(上傳.htaccess)
源碼審計
點擊右上角的提示, 發(fā)現(xiàn)這關卡限制上傳的文件后綴還是挺多的, 例如第三關的php3, php5這些后綴都被禁止掉了, 但是還是有漏網(wǎng)之魚的, 就是.htaccess
文件
.htaccess
文件是apache服務器中的一個配置文件,它負責相關目錄下的網(wǎng)頁配置。通過htaccess文件, 可以實現(xiàn)網(wǎng)頁301重定向、自定義404頁面、改變文件擴展名、允許/阻止特定的用戶訪問目錄等等。
要注意的是, 當php版本高于5.2.17時,.htaccess
文件上傳漏洞就不再存在, 所以說這個漏洞在實戰(zhàn)環(huán)境下幾乎時不肯能存在的
演示步驟
上傳.htaccess
文件, 文件內容如下:
<FilesMatch "webshell">
Sethandler application/x-httpd-php
</FilesMatch>
.htaccess會改變uploads這個目錄下的文件解析規(guī)則, 調用php的解析器去解析一個文件名只需包含
“webshell”
字符串的任意文件簡單來說, 若一個文件的文件名為
webshell.jpg
, 其內容是phpinfo()
, 那么apache就會調用php解析器去解析此文件
隨后上傳webshell.jpg, 文件內容如下:
<?php phpinfo();?>
上傳成功后查看文件路徑, 可以發(fā)現(xiàn)網(wǎng)站使用php解析了webshell.jpg里的內容, 執(zhí)行了phpinfo()
代碼
pass-5(后綴添加. .)
源碼審計
首先看下$file_name = deldot($filename)
這行代碼, 它的作用是將上傳文件最末尾的"."去除掉了, 我們可以利用它這個機制來繞過后綴限制, 例如上傳一個文件名為webshell.php. .
, 經(jīng)過deldot函數(shù)的處理后文件名為webshell.php.
然后再看下strrchr
函數(shù), 該函數(shù)的作用是返回的字符串從指定字符的位置開始,包含指定字符。因此,$file_ext
變量中保存的是文件的擴展名, 也就是說最終$file_ext
的值為.
$deny_ext
是一個存有黑名單后綴的數(shù)組, 后面代碼判斷$file_ext
是否是黑名單后綴, 由于$file_ext
的值為.
, 并不屬于限制后綴, 因此能夠上傳成功
演示步驟
如下圖所示, burpsuite抓取上傳文件的數(shù)據(jù)包, 將文件名稱修改成webshell.php. .
, 隨后文件上傳成功
查看上傳的文件, 雖然文件后綴有個.
, 但是依舊不影響網(wǎng)站對其的解析
pass-6(后綴大小寫)
源碼審計
審計源碼可以發(fā)現(xiàn), 此關卡去除了大小寫轉換函數(shù), 也就是說可以通過構造大小后綴來繞過限制, 例如Php,PHP這種后綴
演示步驟
上傳webshell.php并抓包, 修改文件名為webshell.Php
上傳成功后訪問腳本文件, 如下圖所示
pass-7(空格繞過)
源碼審計
審計源碼可以發(fā)現(xiàn), 此關卡去除了刪除末尾空格的函數(shù), 這樣我們可以在文件后綴末尾添加空格來實現(xiàn)繞過
演示步驟
抓取上傳文件的數(shù)據(jù)包, 修改文件名稱, 在文件后綴末尾后面添加空格, 如下圖所示
上傳文件成功后訪問腳本文件
pass-8(后綴添加.)
源碼審計
通過審計源碼可知, 此關卡去除了刪除文件名稱最末尾的字符’.'的函數(shù), 因此可以通過在文件后綴添加"."來繞過
演示步驟
抓包修改文件名為webshell.php.
文件上傳成功后訪問腳本文件, 雖然文件名為webshell.php.
, 但是網(wǎng)站依舊能夠解析
pass-9(::$data繞過)
源碼審計
通過審計源碼可以發(fā)現(xiàn), 此關卡去除了刪除字符串"::$data
"的函數(shù), 這樣我們可以在文件后綴末尾添加字符串"::$data
", 這樣網(wǎng)站后端識別的后綴名即為.php::$data
, 不在黑名單當中, 可以上傳成功
其次, 根據(jù)Windows系統(tǒng)的特性, 在目錄創(chuàng)建文件時會忽略文件名稱的::$data
進行創(chuàng)建, 也就是說, 最后創(chuàng)建的文件后綴依然是php
演示步驟
上傳文件并抓包, 在文件后綴末尾添加字符串::$data
打開上傳文件所在目錄進行查看, 可以發(fā)現(xiàn)文件后綴經(jīng)過windows系統(tǒng)過濾后, 變成了php后綴
訪問上傳的腳本文件
pass-10(后綴添加. .)
源碼審計
此關卡的黑名單后綴基本完善了, 就連.htaccess
后綴也被禁掉了, 只能用老辦法了, 在文件后綴末尾添加. .
演示步驟
抓包修改文件名稱為webshell.php. .
上傳文件后訪問腳本文件
pass-11(雙寫后綴繞過)
源碼審計
此關卡用到了str_ireplace()
函數(shù), 作用是將文件名稱中的黑名單后綴替換成空格, 并且此函數(shù)的特性是忽略大小寫, 所以無法使用之前的大小寫后綴進行繞過, 但是可以雙重寫后綴來繞過, 比如構造一個后綴為pphphp, 此函數(shù)是從前往后尋找可替換的字符串, 因此經(jīng)過替換后的后綴變成了php
演示步驟
抓包修改文件后綴為pphphp
上傳文件成功后訪問腳本文件
pass-12(%00截斷繞過)
源碼審計
下圖所示為此關卡的源碼, 后面我會挑幾行關鍵的代碼來解釋
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-8o8SUNJQ-1673666521408)(https://img2023.cnblogs.com/blog/1779065/202301/1779065-20230114111605645-413484507.png)]
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
這條代碼的作用是獲取文件的擴展名。簡單來說就是獲取文件名稱最后一個"."后面的字符串當作文件后綴
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
通過GET請求來獲取save_path
參數(shù)的值, 也就是說這個值是可控的, 若我們將這個值修改成../upload/webshell.php%00
, 也就是在文件名后面添加截斷符號%00
,這樣做的作用是將截斷數(shù)據(jù), Windows創(chuàng)建文件時會忽略后面 rand(10, 99).date("YmdHis").".".$file_ext
這行代碼, 這樣$img_path變量值就變成了../upload/webshell.php
%00
是 URL 編碼中的一個字符,它表示一個空字符(NULL 字符)
move_uploaded_file($temp_file,$img_path)
將文件的名稱修改成webshell.jpg
, 通過這行代碼可以將webshell.jpg移動至upload目錄, 并將文件名修改成webshell.php
%00
截斷法只適用于php版本低于5.3的, 且需要在phpstudy把魔術引號函數(shù)magic_quotes_gpc關閉掉, 關閉方法如下圖所示
步驟演示
上傳webshell.php文件, 抓包修改文件名稱為webshell.jpg
, 修改save-path參數(shù)為../upload/webshell.php%00
文件上傳成功后查看腳本文件, 將后面的無效內容去除掉, 即可訪問成功
pass-13(%00截斷繞過)
源碼審計
此關卡與pass-12相似, 但不同的是pass-12的save_path參數(shù)是通過get請求獲取的, 而這關是通過post請求獲取的, get請求傳遞的參數(shù)后端會自動進行解碼, 但是post請求傳遞的參數(shù)后端不會自動解碼, 因此我們要對截斷符%00
進行url解碼
步驟演示
抓包修改post請求數(shù)據(jù)為../upload/webshell.php%00
, 并對%00
進行url解碼
下圖是%00
解碼后的結果, 是一個肉眼看不到的空字符, 隨后還需將文件名修改成webshell.jpg
上傳文件后訪問腳本
pass-14(圖片馬)
源碼審計
此關卡通過獲取上傳文件的內容的前兩個字節(jié)來判斷該文件的類型, 簡單來說就通過識別文件頭來判斷文件類型, 我們只需修改文件頭為圖片格式的, 例如gif文件頭:GIF89A, 就能實現(xiàn)繞過
步驟演示
在文件內容前面添加字符串"GIF89A"(這是gif格式的文件頭), 并將文件后綴修改成jpg
當然你也可以使用windows的copy命令來合并文件, 首先找一個圖片文件1.jpg, 然后將其與webshell.php合并成webshell.jpg
copy 1.jpg + webshell.php webshell.jpg
隨后上傳文件配合文件包含漏洞解析腳本
pass-15(圖片馬之getimagesize函數(shù))
源碼審計
這關和上一關很相似, 只不過這關是使用 getimagesize()
函數(shù)獲取圖像的信息。getimagesize()
函數(shù)返回一個數(shù)組,數(shù)組的第三個元素是圖像的類型, 而該函數(shù)會通過讀取文件頭部的幾個字符串(即文件頭), 來判斷是否為正常圖片的頭部, 我們只需將頭部內容修改成圖片文件的頭部, 例如添加文件頭GIF89A, 就可以繞過此機制
隨后使用 image_type_to_extension()
函數(shù)將圖像的類型轉換為擴展名
步驟演示
和上一關的操作沒啥區(qū)別, 在文件內容前面添加GIF89A, 并保存為jpg格式文件
隨后上傳文件配合文件包含漏洞
pass -16(圖片馬之exif_imagetype函數(shù))
源碼審計
根據(jù)提示, 此關卡需要開啟php_exif模塊, 需要修改php.ini配置文件去開啟它, 如下圖所示
此關卡使用exif_imagetype()
函數(shù)來識別文件類型, 此函數(shù)和getimagesize()
的原理差不多, 都是通過讀取文件頭來判斷文件類型
步驟演示
操作步驟和上一關一樣, 這里就不演示了
pass-17(圖片馬之二次渲染)
源碼審計
此關卡使用imagecreateformjpeg()
函數(shù)來對上傳的圖片文件進行二次渲染,隨后返回一個新的圖像文件, 由于新的圖像文件是經(jīng)過二次渲染后的, 所以我們在圖像中布置的惡意代碼也會被刷新, 從而導致不能配合文件包含漏洞來解析腳本文件
但是, 二次渲染后的文件并不是所有文件內容都會被刷新, 有一小部分是沒有修改的, 我們只需找到這一小部分內容的位置, 然后將代碼插入進去, 就能實現(xiàn)繞過
步驟演示
首先我們上傳一個包含phpinfo()
代碼的gif圖片, 圖片雖然成功上傳, 但是卻無法配合文件包含漏洞進行解析, 如下圖所示, 頁面顯示了一堆亂碼, 這顯然不是我們想要的結果
我們將上傳前和上傳后的gif文件放到winhex工具中進行對比,其中webshell.gif是上傳前的, 1400.gif是上傳后的
很明顯可以看出, 文件末尾的phpinfo代碼經(jīng)過二次渲染后, 已經(jīng)不見了, 被刷掉了
但是二次渲染還是可以繞過的, 只要找到?jīng)]有被它渲染過的地方, 例如, 如下圖所示的這個地方來寫入我們的代碼, 可能你會有疑問, 為什么不在前面那段空白寫入代碼, 這是因為前面的內容屬于文件頭, 如果寫入了代碼就相當于破壞了文件頭, 這樣就不能上傳文件了
既然找到地方了, 那么就往此處寫代碼嘍, 首先復制文件末尾的phpinfo代碼的十六進制數(shù)值
然后往找到的地方寫入代碼, 來覆蓋原先的代碼(注意:不是粘貼, 粘貼是插入代碼)
上傳winhex修改后的文件, 配合文件包含漏洞解析gif圖片的內容
pass-18(條件競爭)
源碼審計
此關卡主要考察條件競爭, 如下代碼所示, 后端先將文件上傳至網(wǎng)站目錄, 然后才對文件進行檢驗來決定是否刪除這個文件, 如果我們在上傳文件的瞬間, 也就是文件沒被刪除的時候, 訪問這個文件, 就能實現(xiàn)繞過
步驟演示
首先上傳一個webshell.php并抓包, 將包發(fā)送給intruder模塊
在intrude的負載選項設置成如下圖所示, 設置完后點擊右上角的開始攻擊
然后再抓取訪問上傳文件的數(shù)據(jù)包并發(fā)送給intruder, 負載選項的設置和上述一致, 點擊開始攻擊
然后查看訪問上傳文件數(shù)據(jù)包的爆破結果, 找響應長度大的, 對其鼠標右鍵, 在瀏覽器中顯示響應
隨后復制此鏈接至開啟了burpsuite代理的瀏覽器中打開
pass-19(.7z后綴繞過)
源碼審計
首先創(chuàng)建了一個Myupload類, 并調用了此類的upload函數(shù), 傳遞UPLOAD_PATH
作為upload函數(shù)的參數(shù), UPLOAD_PATH
的值是上傳文件的所在目錄, 也就是/upload
轉到upload
函數(shù)的定義處, 這里要重點注意setDir
這個函數(shù), 此函數(shù)用于設置文件上傳的目錄
轉到setDir
函數(shù)的定義處, 此處有一行代碼寫錯了, cls_upload_dir的值應該糾正為$dir.'/'
, 至于為何要這樣糾正, 后面我會講述
繼續(xù)將代碼往下翻, 此處調用了move函數(shù)
轉到move函數(shù)定義處可以發(fā)現(xiàn), 要是沒有糾正上述代碼, 那么cls_upload_dir的值就為upload
, 此變量與$cls_filenam
e拼接在一起后構成的文件名如下圖2所示, 上傳的文件就不會放在upload目錄下, 而是放在網(wǎng)站根目錄下
如下代碼規(guī)定了白名單后綴, 這里要特別注意7z這個后綴, 這后綴瀏覽器是無法解析的, 當瀏覽器遇到無法解析的后綴時, 就會往前解析, 要是我們上傳文件名為webshell.php.7z
, 那么瀏覽器就會解析.php
后綴而不會解析.7z
后綴
從下述代碼可以看出, 此關卡和上一關差不多一個性質, 都是上傳了文件后才對文件進行檢驗
步驟演示
此關卡的操作步驟上一關差不多, 不同的是這關需要將文件名修改成webshell.php.7z
, 詳細操作這里就不再演示
pass-20(%00截斷繞過)
源碼審計
從白名單后綴可以看出, 并沒有嚴格限制大小寫, 只要將后綴名修改成PHP就可以繞過, 或者使用截斷符%00
繞過, 文件名是通過POST請求的save_name參數(shù)來獲取的
步驟演示
上傳webshell.php文件, 將save_name參數(shù)值的文件后綴修改成PHP
使用上述方法上傳文件成功后訪問腳本文件
或者使用%00截斷符號
pass-21(數(shù)組繞過)
源碼審計
首先判斷上傳的文件類型是否屬于: image/jpeg
, image/png
, image/gif
然后檢測上傳的文件名稱是否為數(shù)組, 若不為數(shù)組, 則使用explode函數(shù)將文件名按照“.”進行分割, 并將結果轉換為小寫, 這個 $file
會是一個數(shù)組, 數(shù)組的第一項是文件名,第二項是文件擴展名
也就是說如果我們上傳的文件名稱若為數(shù)組, 那么他就不會執(zhí)行這行代碼, 而是繼續(xù)往下執(zhí)行代碼
例如此處我傳遞了兩個數(shù)組元素, 分別是save_name[0]=upload.php
和save_name[2]=jpg
end($file)
獲取到的就是這個數(shù)組的最后一個元素,也就是文件擴展名, 然后對這個擴展名進行檢驗, 由于我們構造數(shù)組的最后一個元素為白名單后綴jpg, 因此能夠上傳文件
使用 reset()
函數(shù)獲取數(shù)組的第一個元素,即upload.php
, $file[count-1]
的值為空(下面的代碼很好解釋了此值為何為空), 最終$file_name
的值為upload.php
<?php
header("Content-Type:text/html;charset=utf-8");
$save_name[0]="upload.php";
$save_name[2]="jpg";
print_r(count($save_name)); //輸出數(shù)組的個數(shù):2
print_r($save_name[count($save_name)-1]); //輸出$save_name[1]的值:空
?>
步驟演示
首先上傳一個webshell.php文件, 抓包修改數(shù)據(jù)如下圖所示
注意: 在傳遞數(shù)組元素值時都會多留一條空行, 不要將這條空行刪除, 否則文件會上傳失敗
訪問腳本文件
文章來源:http://www.zghlxwxcb.cn/news/detail-758078.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-758078.html
到了這里,關于全面了解文件上傳漏洞, 通關upload-labs靶場的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!