文件上傳方法總結


以upload-labs講解   

項目地址https://github.com/c0ny1/upload-labs/releases

每道題都要通過上面這張圖判斷文件校驗的方式,才能有大體繞過思路


PASS 01      前端js校驗

image嘗試上傳符合條件的文件,將一句話木馬后綴改為jpg,抓包修改成php文件。

PASS 02       MIME文件類型校驗

image

提示文件類型不正確,可能是MIME校驗

image

image


PASS 03        php多種擴展名繞過

上傳php文件時出現提示,php被加入了黑名單,並且會將上傳的文件重新命名,無法通過上傳.htaccess文件繞過,大小寫失敗了,嘗試上傳php3,phtml等其他擴展名文件繞過黑名單限制

image

image


PASS 04     上傳.htaccess文件繞過

image

通過上傳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[空格]

image


PASS 07       Windows特性文件命名規則

原理同pass 06,通過Windows文件命名規則繞過,抓包將文件改為1.php.即可

綜合pass06和pass07,碰到此類型的都可以將文件修改為1.php[空格].


PASS 08      Windows特性   ::$DATA繞過

在php+Windows的情況下:如果文件名+"::$DATA" 會把 "::$DATA"之后的數據當成文件流處理,不會檢測后綴名且保持”::$DATA”之前的文件名

抓包修改1.php為如圖所示

image

上傳成功后查看鏈接,鏈接為http://192.168.135.144/upload/202004231705477566.php::$data

查看http://192.168.135.144/upload/202004231705477566.php 即為已上傳文件

image


PASS 09

從源碼可以看出這次拼接的路徑是$file_name的值,結合Windows特性構造文件

image

image

image


PASS 10     后綴名雙寫繞過

通過上傳1.php文件后查看文件后綴.php被過濾,猜測可能之過濾一次,嘗試雙寫后綴名繞過,這里雙寫要注意:1.pphphp和1.phphpp產生的文件是不同的,過濾是從左往右的,所以1.phphpp會生成文件1.hpp

image


PASS 11     %00截斷繞過

通過測試得知是后端白名單限制,對內容並未過濾

image

image

代碼分析發現最終返回的圖片鏈接是”存儲路徑名+重命名后的文件名“,看到這個我們可以聯想到使用%00截斷路徑。

截斷條件:1.php版本小於5.3.4        2.php.ini的magic_quotes_gpc為OFF狀態(默認為OFF)

image

image

訪問鏈接http://192.168.135.144/upload/1.php  上傳成功

image


PASS 12     %00截斷繞過

image

同pass 11一樣使用00截斷繞過,但這里是通過POST方式,由於POST不像GET可以自動解碼%00,所以需要手動解碼,如下

image

image

訪問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

802776a027b4b20d43c42b91f8e7ce2a

PNG和JPG通過腳本可以生成,使用方法:

1.先將一張正常的jpg圖片上傳,上傳后將服務器存儲的二次渲染的圖片保存下來。

2.將保存下來經過服務器二次渲染的那張jpg圖片,用腳本進行處理生成payload.jpg

3.然后再上傳payload.jpg


PASS 17  利用競爭條件繞過

可以從代碼看到,文件是先上傳再判斷是否是合法文件,不是則將文件刪除

image

繞過思路:可以上傳一個php文件,文件的功能是寫一句話木馬,然后再重復訪問該php文件,目的是卡在刪除之前執行該文件,上傳的php文件代碼如下:

<?php

fputs(fopen('eval.php','w'),'<?php eval($_POST[cmd]);?>');

?>

<?php $f= fopen ("shell.php","w") ; fputs ($f,'<?php phpinfo();?>'); ?>


PASS 18   條件競爭上傳圖片馬


PASS  19   利用/.達到00截斷的效果

move_uploaded_file會忽略掉文件末尾的/.

image

因此可以構造smile.php/. 達到00截斷的作用image.png



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

image.png

image.png


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM