文件上傳之繞過

一般防止上傳漏洞手法

1、客戶端檢測:客戶端使用JavaScript檢測,在文件未上傳時(shí),就對文件進(jìn)行驗(yàn)證
    //任何客戶端的驗(yàn)證都是不安全的,客戶端驗(yàn)證目的是防止用戶輸入錯誤、減少
    //服務(wù)器開銷,而服務(wù)端驗(yàn)證才可以真正防御攻擊者。  
2、服務(wù)器端檢測:服務(wù)端腳本一般會檢測文件的MIME類型,檢測文件擴(kuò)展名是否合法

客戶端檢測

客戶端驗(yàn)證代碼形如下:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>圖片上傳</title>
    <script type="text/javascript">
    function checkFile(){
        var flag = false;
        var str = document.getElementById("file").value;
        str = str.substring(str.lastIndexOf('.') + 1);
        var arr = new Array('png','bmp','gif','jpg');
        for (var i=0;i<arr.length;i++){
            if(str==arr[i]){
                flag = true;
            }
        }
        if(!flag){
            alert('文件不合法!');
        }
        return flag;
    }
    </script>
</head>
<body>
    <form action="upload.php" method="post" onsubmit="checkFile()" enctype="multipart/form-data">
        <input type="file" name="file" id="file" /><br/>
        <input type="submit" value="提交" name="submit" />
    </form>
</body>
</html>

接收文件的腳本upload.php代碼如下:

<?php
if(isset($_POST["submit"])){
    $name = $_FILES['file']['name'];
    $name = md5(date('Y-m-d h:m:s')).strrchr($name,".");
    $size = $_FILES['file']['size'];
    $tmp = $_FILES['file']['tem_name'];
    move_uploaded_file($tmp,$name);
    echo "文件上傳成功!path:".$name;
}
?>

繞過:

1、可以用firebug將form表單中的onsubmit事件刪除,這樣就可以繞過驗(yàn)證。
2、使用Burp Suite:
    1)先將木馬文件的擴(kuò)展名改為一張正常圖片的擴(kuò)展名,如jpg
    2)上傳時(shí)使用Burp Suite攔截?cái)?shù)據(jù)包,將木馬文件擴(kuò)展名改為php就可繞過客戶端驗(yàn)證。
    注意:這里修改文件名字后,請求頭中的Content-Length的值也要改

服務(wù)端檢測

服務(wù)端分為6項(xiàng):

* 黑名單與白名單驗(yàn)證
* MIME驗(yàn)證
* 目錄驗(yàn)證
* 截?cái)嗌蟼鞴?* .htaccess文件攻擊
* 檢測文件內(nèi)容

黑名單與白名單驗(yàn)證

  • 黑名單過濾方式

<?php
$Blacklist = array('asp','php','jsp','php5','asa','aspx'); //黑名單
if (isset($_POST["submit"])){
$name = $FILES['file']['name']; //接收文件名
$extension = substr(strrchr($name, ".") , 1); //得到擴(kuò)展名
$boo = false;
foreach ($Blaklist as $key => $value){
if ($value==$extension) { //迭代判斷是否命中
$boo = true;
break; //命中后直接退出循環(huán)
}
}
if (!$boo) { //若沒有被命中,則進(jìn)行上傳操作
$size = $_FILES['file']['size']; //接收文件大小
$tmp = $FILES['file']['temp_name']; //臨時(shí)路徑
move_uploaded_file($tmp, $name); //移動臨時(shí)文件到當(dāng)前文件目錄
} else {
echo "文件不合法!!";
}
}
?>

對于上面的過濾可以通過如下方法繞過:
  • 從黑名單中找到web開發(fā)者忽略的擴(kuò)展名,如:cer
  • 沒有對擴(kuò)展名進(jìn)行大小寫轉(zhuǎn)換,在window平臺依然可以大小寫繞過
  • 在window下,若文件名以"."或者空格作為結(jié)尾,系統(tǒng)會自動去除"."與空格,
    所以可以上傳以“asp.”和“asp_”為擴(kuò)展名的文件
  • 0x00截?cái)嗬@過
  • 解析漏洞
* 白名單過濾方式

> ```php
<?php
$WhiteList = array('rar','jpg','png','bmp','gif','jpg','doc');
if(isset($_POST["submit"])){
    $name = $_FILES['file']['name'];
    $extension = substr(strrchr($name,"."),1);
    $boo = false;
    foreach($WhiteList as $key => $value){
        if($value==$extension){
            $boo = true;
        }
    }
    if($boo){
        $size = $_FILES['file']['size'];
        $tmp = $_FILES['file']['tmp_name'];
        move_uploaded_file($tmp,$name);
        echo "文件上傳成功!<br/>path:".$name;
    }else{
        echo "文件不合法!";
    }
}
?>

繞過方法:

* 0x00截?cái)嗬@過
* 此時(shí)若在iis6.0,則可以將木馬名改為test.asp;1.jpg來上傳,從而通過驗(yàn)證
* 配合解析漏洞

MIME驗(yàn)證

對文件MIME類型做驗(yàn)證的PHP代碼如下:

<?php
if($_FILES['file']['type']==" image/jpeg"){
    $imageTempName = $_FILES['file']['tmp_name'];
    $imageName = $_FILES['file']['name'];
    $last = substr($imageName,strrpos($imageName,"."));
    if(!is_dir("uploadFile")){
        mkdir("uploadFile");
    }
    $imageName = md5($imageName).$last;
    move_upload_file($imageTempName,"./uploadFile/".$imageName);
    echo("文件上傳成功! path = /uploadFile/$imageName");
}else{
    echo("文件上傳類型錯誤,請重新上傳...");
    exit();
}
?>

未修改MIME類型,上傳失?。?/p>

upload_vuln_not_alter_mime.png

修改MIME類型,上傳成功:


upload_vuln_alter_mime.png

目錄驗(yàn)證

文件上傳時(shí)通常允許用戶將文件放到指定的目錄中,若目錄存在則將文件寫入目錄,否則新建目錄然后寫入,若為iis6.0則可以利用這個(gè)漏洞,客戶端上傳代碼如下:

<html>
<head>
    <meta charset="UTF-8">
    <title>up</title>
</head>
<body>
    <form action="upload.php" method="post" enctype="multipart/form-data">
        <input type="file" name="file" /><br/>
        <input type="hidden" name="Extension" value="up" />
        <input type="submit" value="提交" name="submit" />
    </form>
</body>
</html>

服務(wù)端PHP接收文件的代碼如下:

<?php
if($_FILES['file']['type']=="image/jpeg"){
    $imageTempName=$_FILES['file']['tmp_name'];
    $imageName=$_FILES['file']['name'];
    $last=substr($imageName,strrpos($imageName,"."));
    if($last!=".jpg"){
        echo("mime error!<br/>");
    }
    $Extension=$_POST['Extension'];
    if(!is_dir($Extension)){
        mkdir("./$Extension");
        echo "mkidr $Extension succesfully"."<br/>";
    }
    $imageName=md5($imageName).$last;
    move_uploaded_file($imageTempName,"./$Extension/".$imageName);
    echo("upload ok! path = /$Extension/$imageName");
} else {
    echo("type error...");
    exit();
}
?>

查看上傳到了那個(gè)文件:


upload_vuln_check_asp_dirname.png

將文件改名:


upload_vuln_alter_upload_dirname.png

upload_vuln_check_asp_dirname.png

截?cái)嗌蟼鞴?/h4>

截?cái)嗌蟼鞴粼贏SP程序中比較常見(在PHP、JSP中也有)
先上傳正常后綴的圖片馬:


upload_vuln_upload_normal_picture.png

更改圖片名字:


upload_vuln_alter_picture_name.png

截?cái)啵?br>
upload_vuln_truncate_picture_name.png

上傳成功:
upload_vuln_upload_success.png

.htaccess文件攻擊

通過.htaccess文件調(diào)用php解析器去解析一個(gè)文件名中只要包含"haha"這個(gè)字符串的任意文件,無論擴(kuò)展名是什么(沒有也行),都以php的方式來解析,.haccess文件代碼如下:

<FilesMatch "haha">
SetHandler application/x-httpd-php
</FilesMatch>

或者如下,上傳一個(gè)文件名為evil.gif的圖片馬:

<FilesMatch "evil.gif">
SetHandler application/x-httpd-php
</FilesMatch>

檢測文件內(nèi)容

  • 文件幻數(shù)檢測
    在文件首部加上如下幻數(shù),后面跟一句話木馬即可
JFIF    FF D8 FF E0 00 10 4A 46 49 46
GIF89a  47 49 46 38 39 61
PNG     89 50 4E 47
  • 文件相關(guān)信息檢測
    通常用的getimagesize()函數(shù),只需要在幻數(shù)基礎(chǔ)上加一些文件信息就行了,如下:
GIF89a
(...some binary data for image...)
<?php phpinfo(); ?>
(... skipping the rest of binary data ...)
  • 文件加載檢測
    服務(wù)端會調(diào)用API或函數(shù)對文件進(jìn)行加載測試,常見的是圖像渲染測試,變態(tài)的甚至是二次渲染:
對渲染/加載測試的攻擊方式是代碼注入繞過
對二次渲染的攻擊方式是攻擊文件加載器本身

補(bǔ)充

除了上述的.htaccess文件攻擊,還可以用.user.ini進(jìn)行文件攻擊
當(dāng)中間鍵是以fastcgi運(yùn)行的php都可以用這個(gè)方法,.user.ini能被動態(tài)加載,它也有兩個(gè)配置項(xiàng):
auto_append_file和auto_prepend_file,只要在.user.ini中添加auto_prepend_file=aa.jpg
這句話,就可以讓其他php文件執(zhí)行前自動包含aa.jpg,和require()類似。
upload_vuln_file_attack1.png

upload_vuln_file_attack2.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容