原文鏈接:先知技術社區
0x00 前言
玩waf當然也要講究循序漸進,姊妹篇就寫文件上傳好了,感覺也就SQLi和Xss的WafBypass最體現發散性思維的,而文件上傳、免殺、權限提升這幾點的Bypass更需要的是實戰的經驗。本文內容為沉淀下來的總結以及一些經典案例。想到哪寫到哪,所以可能不是很全。創造姿勢不易,且行且珍惜。(案例圖不好上,畢竟是upload的Bypass,就直接上姿勢)
閱讀此文你會發現新老姿勢都有,因為我是想系統的寫一寫,文件上無非就是結合各種特性或waf缺陷。輟寫時想過一個問題,如何歸攏哪些屬于文件上傳Bypass的范疇?打個比方:
上傳正常.jpg的圖片 #成功
上傳正常.php #攔截
繞過.php文件的filename后進行上傳 #成功
使用繞過了filename的姿勢上傳惡意.php #攔截
以上這么個邏輯通常來講是waf檢測到了正文的惡意內容。再繼續寫的話就屬于免殺的范疇了,過于模糊并且跑題了,并不是真正意義上的文件上傳Bypass,那是寫不完的。
0x01 搞起
上傳文件(歪脖騷)時waf會檢查哪里?
請求的url
Boundary邊界
MIME類型
文件擴展名
文件內容
常見擴展名黑名單:
asp|asa|cer|cdx|aspx|ashx|ascx|asax
php|php2|php3|php4|php5|asis|htaccess
htm|html|shtml|pwml|phtml|phtm|js|jsp
vbs|asis|sh|reg|cgi|exe|dll|com|bat|pl|cfc|cfm|ini
個人寫的“稍微”全一點,實際上waf的黑名單就不一定這么全了。
測試時的準備工作:
- 什么語言?什么容器?什么系統?都什么版本?
- 上傳文件都可以上傳什么格式的文件?還是允許上傳任意類型?
- 上傳的文件會不會被重命名或者二次渲染?
0x02 容器特性
有些很老的特性其實也是最開始繞waf的基礎,這里就一筆帶過了。
Apache1.X 2.X解析漏洞:
Apache在以上版本中,解析文件名的方式是從后向前識別擴展名,直到遇見Apache可識別的擴展名為止。
Win2k3 + APACHE2.0.59 + PHP

IIS6.0兩個解析缺陷:
- 目錄名包含
.asp、.asa、.cer的話,則該目錄下的所有文件都將按照asp解析。例如:

- 文件名中如果包含
.asp;、.asa;、.cer;則優先使用asp解析。例如:

有一點需要注意,如果程序會將上傳的圖片進行重命名的話就gg了。
Nginx解析漏洞:
- Nginx 0.5.*
- Nginx 0.6.*
- Nginx 0.7 <= 0.7.65
- Nginx 0.8 <= 0.8.37
以上Nginx容器的版本下,上傳一個在waf白名單之內擴展名的文件shell.jpg,然后以shell.jpg.php進行請求。
- Nginx 0.8.41 – 1.5.6:
以上Nginx容器的版本下,上傳一個在waf白名單之內擴展名的文件shell.jpg,然后以shell.jpg%20.php進行請求。
PHP CGI解析漏洞:
IIS 7.0/7.5
Nginx < 0.8.3
以上的容器版本中默認php配置文件cgi.fix_pathinfo=1時,上傳一個存在于白名單的擴展名文件shell.jpg,在請求時以shell.jpg/shell.php請求,會將shell.jpg以php來解析。
多個Content-Disposition:
在IIS的環境下,上傳文件時如果存在多個Content-Disposition的話,IIS會取第一個Content-Disposition中的值作為接收參數,而如果waf只是取最后一個的話便會被繞過。
Win2k8 + IIS7.0 + PHP

請求正文格式問題:
Content-Disposition: form-data; name="file1"; filename="shell.asp"
Content-Type: application/octet-stream
正常的upload請求都是以上這樣,然而這個格式也并非強制性的,在IIS6.0下如果我們換一種書寫方式,把filename放在其他地方:
Win2k3 + IIS6.0 + ASP

結合.htaccess指定某些文件使用php來解析:
這個方法通常用于繞過waf黑名單的,配置該目錄下所有文件都將其使用php來解析:

0x03 系統特性
Windows特殊字符:
當我們上傳一個文件的filename為shell.php{%80-%99}時:

waf可能識別為.php{%80-%99},就會導致被繞過。
Win2k8 + IIS7.0 + PHP

exee擴展名:
上傳.exe文件通常會被waf攔截,如果使用各種特性無用的話,那么可以把擴展名改為.exee再進行上傳。
NTFS ADS特性:
ADS是NTFS磁盤格式的一個特性,用于NTFS交換數據流。在上傳文件時,如果waf對請求正文的filename匹配不當的話可能會導致繞過。

Windows在創建文件時,在文件名末尾不管加多少點都會自動去除,那么上傳時filename可以這么寫shell.php......也可以這么寫shell.php::$DATA.......。
Win2k8 + IIS7.0 + PHP

0x04 waf缺陷
匹配過于嚴謹:
- 一個空格導致安全狗被繞過:
Content-Type: multipart/form-data; boundary=---------------------------4714631421141173021852555099
嘗試在boundary后面加個空格或者其他可被正常處理的字符:
boundary =---------------------------4714631421141173021852555099
Win2k3 + IIS6.0 + ASP

- 以上也能說明一個問題,安全狗在上傳文件時匹配各個參數都十分嚴謹,不過IIS6.0以上也變的嚴謹了,再看看其他的地方:
每次文件上傳時的Boundary邊界都是一致的:
Content-Type: multipart/form-data; boundary=---------------------------4714631421141173021852555099
Content-Length: 253
-----------------------------4714631421141173021852555099
Content-Disposition: form-data; name="file1"; filename="shell.asp"
Content-Type: application/octet-stream
<%eval request("a")%>
-----------------------------4714631421141173021852555099--
但如果容器在處理的過程中并沒有嚴格要求一致的話可能會導致一個問題,兩段Boundary不一致使得waf認為這段數據是無意義的,可是容器并沒有那么嚴謹:
Win2k3 + IIS6.0 + ASP

修改Content-Type的MIME類型:
Win2k3 + IIS6.0 + ASP

ASCII > 127的字符:

數據過長導致的繞過:
- waf如果對Content-Disposition長度處理的不夠好的話可能會導致繞過,例如:
Win2k3 + IIS6.0 + ASP

- 基于文件名:
基于構造長文件名

如果web程序會將filename除了擴展名的那段重命名的話,那么還可以構造更多的點、符號等等。

- 特殊的長文件名:
文件名使用非字母數字,比如中文等最大程度的拉長,不行的話再結合一下其他的特性進行測試:
shell.asp;王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王.jpg
0x05 End
在這里放上個人之前總結的30個上傳繞過姿勢:
1. filename在content-type下面
2. .asp{80-90}
3. NTFS ADS
4. .asp...
5. boundary不一致
6. iis6分號截斷asp.asp;asp.jpg
7. apache解析漏洞php.php.ddd
8. boundary和content-disposition中間插入換行
9. hello.php:a.jpg然后hello.<<<
10. filename=php.php
11. filename="a.txt";filename="a.php"
12. name=\n"file";filename="a.php"
13. content-disposition:\n
14. .htaccess文件
15. a.jpg.\nphp
16. 去掉content-disposition的form-data字段
17. php<5.3 單雙引號截斷特性
18. 刪掉content-disposition: form-data;
19. content-disposition\00:
20. {char}+content-disposition
21. head頭的content-type: tab
22. head頭的content-type: multipart/form-DATA
23. filename后綴改為大寫
24. head頭的Content-Type: multipart/form-data;\n
25. .asp空格
26. .asp0x00.jpg截斷
27. 雙boundary
28. file\nname="php.php"
29. head頭content-type空格:
30. form-data字段與name字段交換位置
文件上傳Bypass可寫的點不多,現有的姿勢也不能拿出來講(笑)重點在于上傳文件時遇到waf能夠準確判斷所攔截的點,目光不能只盯在waf,更多的時注意后端的情況。往往是需要結合哪些語言/容器/系統版本“可以怎樣”、“不可以怎樣”。
PDF 版本下載:wafbypass_upload.pdf
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/219/