以upload-labs講解
項目地址https://github.com/c0ny1/upload-labs/releases
每道題都要通過上面這張圖判斷文件校驗的方式,才能有大體繞過思路
PASS 01 前端js校驗
嘗試上傳符合條件的文件,將一句話木馬后綴改為jpg,抓包修改成php文件。
PASS 02 MIME文件類型校驗
提示文件類型不正確,可能是MIME校驗
PASS 03 php多種擴展名繞過
上傳php文件時出現提示,php被加入了黑名單,並且會將上傳的文件重新命名,無法通過上傳.htaccess文件繞過,大小寫失敗了,嘗試上傳php3,phtml等其他擴展名文件繞過黑名單限制
PASS 04 上傳.htaccess文件繞過
通過上傳jpg圖片發現文件名並未改變,但是各種擴展名大小寫都被限制,嘗試上傳.htaccess文件,內容為
SetHandler application/x-httpd-php
將所有文件解析為ph執行,此時上傳文件改為jpg格式成功上傳,查看解析
PASS 05 后綴名大寫繞過
將后綴名大寫繞過
PASS 06 Windows特性文件命名規則
相比前幾題,大小寫繞過和上傳.htaccess文件已經行不通了。查看源代碼沒有去掉末尾的空格,那可以利用Windows的特性,Windows下xx.jpg[空格]或xx.jpg.這兩類文件都是不允許存在的,若是這樣命名,Windows會默認除去空格或點。
上傳1.php,抓包修改為1.php[空格]
PASS 07 Windows特性文件命名規則
原理同pass 06,通過Windows文件命名規則繞過,抓包將文件改為1.php.即可
綜合pass06和pass07,碰到此類型的都可以將文件修改為1.php[空格].
PASS 08 Windows特性 ::$DATA繞過
在php+Windows的情況下:如果文件名+"::$DATA" 會把 "::$DATA"之后的數據當成文件流處理,不會檢測后綴名且保持”::$DATA”之前的文件名
抓包修改1.php為如圖所示
上傳成功后查看鏈接,鏈接為http://192.168.135.144/upload/202004231705477566.php::$data
查看http://192.168.135.144/upload/202004231705477566.php 即為已上傳文件
PASS 09
從源碼可以看出這次拼接的路徑是$file_name的值,結合Windows特性構造文件
PASS 10 后綴名雙寫繞過
通過上傳1.php文件后查看文件后綴.php被過濾,猜測可能之過濾一次,嘗試雙寫后綴名繞過,這里雙寫要注意:1.pphphp和1.phphpp產生的文件是不同的,過濾是從左往右的,所以1.phphpp會生成文件1.hpp
PASS 11 %00截斷繞過
通過測試得知是后端白名單限制,對內容並未過濾
代碼分析發現最終返回的圖片鏈接是”存儲路徑名+重命名后的文件名“,看到這個我們可以聯想到使用%00截斷路徑。
截斷條件:1.php版本小於5.3.4 2.php.ini的magic_quotes_gpc為OFF狀態(默認為OFF)
訪問鏈接http://192.168.135.144/upload/1.php 上傳成功
PASS 12 %00截斷繞過
同pass 11一樣使用00截斷繞過,但這里是通過POST方式,由於POST不像GET可以自動解碼%00,所以需要手動解碼,如下
訪問http://192.168.135.144/upload/2.php 上傳成功
PASS 13 文件內容頭部檢測
分析代碼可知通過讀文件的前2個字節判斷文件類型,因此直接上傳圖片馬即可,制作方法:
copy 1.jpg /b + shell.php /a webshell.jpg
成功上傳后利用的話還需結合文件包含漏洞。
PASS 14 文件內容頭部檢測
通過代碼得知這里使用getimagesize獲取文件類型,直接上傳圖片馬可繞過
PASS 15 圖片馬繞過
這里用到php_exif模塊來判斷文件類型,同樣可以利用圖片馬直接繞過
PASS 16 圖片二次渲染
繞過思路:對比上傳前和上傳后的圖片的差異,找到相同數據同時又是非圖片數據區的地方,在此處寫入惡意代碼。不同的圖像類型插入方式有區別。
GIF
GIF的二次渲染繞過是最簡單的,將源文件和二次渲染過的文件進行比較,找到源文件中沒有被修改的那段區域,寫入PHP代碼即可。 使用工具winhex
PNG和JPG通過腳本可以生成,使用方法:
1.先將一張正常的jpg圖片上傳,上傳后將服務器存儲的二次渲染的圖片保存下來。
2.將保存下來經過服務器二次渲染的那張jpg圖片,用腳本進行處理生成payload.jpg
3.然后再上傳payload.jpg
PASS 17 利用競爭條件繞過
可以從代碼看到,文件是先上傳再判斷是否是合法文件,不是則將文件刪除
繞過思路:可以上傳一個php文件,文件的功能是寫一句話木馬,然后再重復訪問該php文件,目的是卡在刪除之前執行該文件,上傳的php文件代碼如下:
<?php $f= fopen ("shell.php","w") ; fputs ($f,'<?php phpinfo();?>'); ?>
PASS 18 條件競爭上傳圖片馬
PASS 19 利用/.達到00截斷的效果
move_uploaded_file會忽略掉文件末尾的/.
因此可以構造smile.php/. 達到00截斷的作用
PASS 20 數組+/.繞過
$is_upload = false; $msg = null; if(!empty($_FILES['upload_file'])){ //檢查MIME $allow_type = array('image/jpeg','image/png','image/gif'); if(!in_array($_FILES['upload_file']['type'],$allow_type)){ $msg = "禁止上傳該類型文件!"; }else{ //檢查文件名 $file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name']; if (!is_array($file)) { $file = explode('.', strtolower($file)); } $ext = end($file); $allow_suffix = array('jpg','png','gif'); if (!in_array($ext, $allow_suffix)) { $msg = "禁止上傳該后綴文件!"; }else{ $file_name = reset($file) . '.' . $file[count($file) - 1]; $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH . '/' .$file_name; if (move_uploaded_file($temp_file, $img_path)) { $msg = "文件上傳成功!"; $is_upload = true; } else { $msg = "文件上傳失敗!"; } } } }else{ $msg = "請選擇要上傳的文件!"; }
可以發現$file_name
經過reset($file) . '.' . $file[count($file) - 1];
處理。
如果上傳的是數組的話,會跳過$file = explode('.', strtolower($file));
。
並且后綴有白名單過濾。
而最終的文件名后綴取的是$file[count($file) - 1]
,因此我們可以讓$file
為數組。$file[0]
為smi1e.php/
,也就是reset($file)
,然后再令$file[2]
為白名單中的jpg。
此時end($file)
等於jpg,$file[count($file) - 1]
為空。
而 $file_name = reset($file) . '.' . $file[count($file) - 1];
,也就是smi1e.php/.
,最終move_uploaded_file
會忽略掉/.
,最終上傳smi1e.php
。