文件上傳之繞過(guò)

一般防止上傳漏洞手法

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

客戶端檢測(cè)

客戶端驗(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;
}
?>

繞過(guò):

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

服務(wù)端檢測(cè)

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

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

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

  • 黑名單過(guò)濾方式

<?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) { //若沒(méi)有被命中,則進(jìn)行上傳操作
$size = $_FILES['file']['size']; //接收文件大小
$tmp = $FILES['file']['temp_name']; //臨時(shí)路徑
move_uploaded_file($tmp, $name); //移動(dòng)臨時(shí)文件到當(dāng)前文件目錄
} else {
echo "文件不合法!!";
}
}
?>

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

> ```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 "文件不合法!";
    }
}
?>

繞過(guò)方法:

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

MIME驗(yàn)證

對(duì)文件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("文件上傳類型錯(cuò)誤,請(qǐng)重新上傳...");
    exit();
}
?>

未修改MIME類型,上傳失敗:


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程序中比較常見(jiàn)(在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文件攻擊

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

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

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

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

檢測(cè)文件內(nèi)容

  • 文件幻數(shù)檢測(cè)
    在文件首部加上如下幻數(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)信息檢測(cè)
    通常用的getimagesize()函數(shù),只需要在幻數(shù)基礎(chǔ)上加一些文件信息就行了,如下:
GIF89a
(...some binary data for image...)
<?php phpinfo(); ?>
(... skipping the rest of binary data ...)
  • 文件加載檢測(cè)
    服務(wù)端會(huì)調(diào)用API或函數(shù)對(duì)文件進(jìn)行加載測(cè)試,常見(jiàn)的是圖像渲染測(cè)試,變態(tài)的甚至是二次渲染:
對(duì)渲染/加載測(cè)試的攻擊方式是代碼注入繞過(guò)
對(duì)二次渲染的攻擊方式是攻擊文件加載器本身

補(bǔ)充

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

upload_vuln_file_attack2.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容