個人WafBypass之道(upload篇)

0x00 前言

玩waf固然也要講究按部就班,姊妹篇就寫文件上傳好了,感受也就SQLi和Xss的WafBypass最體現發散性思惟的,而文件上傳、免殺、權限提高這幾點的Bypass更須要的是實戰的經驗。本文內容爲沉澱下來的總結以及一些經典案例。想到哪寫到哪,因此可能不是很全。創造姿式不易,且行且珍惜。(案例圖很差上,畢竟是upload的Bypass,就直接上姿式)php

閱讀此文你會發現新老姿式都有,由於我是想系統的寫一寫,文件上無非就是結合各類特性或waf缺陷。輟寫時想過一個問題,如何歸攏哪些屬於文件上傳Bypass的範疇?打個比方:html

  1. 上傳正常.jpg的圖片 #成功
  2. 上傳正常.php #攔截
  3. 繞過.php文件的filename後進行上傳 #成功
  4. 使用繞過了filename的姿式上傳惡意.php #攔截

以上這麼個邏輯一般來說是waf檢測到了正文的惡意內容。再繼續寫的話就屬於免殺的範疇了,過於模糊而且跑題了,並非真正意義上的文件上傳Bypass,那是寫不完的。web

0x01 搞起

上傳文件(歪脖騷)時waf會檢查哪裏?shell

  1. 請求的url
  2. Boundary邊界
  3. MIME類型
  4. 文件擴展名
  5. 文件內容

常見擴展名黑名單:後端

  1. asp|asa|cer|cdx|aspx|ashx|ascx|asax
  2. php|php2|php3|php4|php5|asis|htaccess
  3. htm|html|shtml|pwml|phtml|phtm|js|jsp
  4. vbs|asis|sh|reg|cgi|exe|dll|com|bat|pl|cfc|cfm|ini

我的寫的「稍微」全一點,實際上waf的黑名單就不必定這麼全了。
測試時的準備工做:安全

  • 什麼語言?什麼容器?什麼系統?都什麼版本?
  • 上傳文件均可以上傳什麼格式的文件?仍是容許上傳任意類型?
  • 上傳的文件會不會被重命名或者二次渲染?

 

0x02 容器特性

有些很老的特性其實也是最開始繞waf的基礎,這裏就一筆帶過了。app

  • Apache1.X 2.X解析漏洞:

Apache在以上版本中,解析文件名的方式是從後向前識別擴展名,直到碰見Apache可識別的擴展名爲止。
Win2k3 + APACHE2.0.59 + PHPjsp

1
IIS6.0兩個解析缺陷:測試

目錄名包含.asp、.asa、.cer的話,則該目錄下的全部文件都將按照asp解析。例如:url

2


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

3


有一點須要注意,若是程序會將上傳的圖片進行重命名的話就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解析漏洞

  1. IIS 7.0/7.5
  2. 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

4

請求正文格式問題:

  1. Content-Disposition: form-data; name="file1"; filename="shell.asp"
  2. Content-Type: application/octet-stream

正常的upload請求都是以上這樣,然而這個格式也並不是強制性的,在IIS6.0下若是咱們換一種書寫方式,把filename放在其餘地方:
Win2k3 + IIS6.0 + ASP

5

結合.htaccess指定某些文件使用php來解析:

這個方法一般用於繞過waf黑名單的,配置該目錄下全部文件都將其使用php來解析:
6

0x03 系統特性

Windows特殊字符:
當咱們上傳一個文件的filename爲shell.php{%80-%99}時:

7

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

8

exee擴展名:
上傳.exe文件一般會被waf攔截,若是使用各類特性無用的話,那麼能夠把擴展名改成.exee再進行上傳。

NTFS ADS特性:
ADS是NTFS磁盤格式的一個特性,用於NTFS交換數據流。在上傳文件時,若是waf對請求正文的filename匹配不當的話可能會致使繞過。

9

Windows在建立文件時,在文件名末尾無論加多少點都會自動去除,那麼上傳時filename能夠這麼寫shell.php......也能夠這麼寫shell.php::$DATA.......。
Win2k8 + IIS7.0 + PHP

10

0x04 waf缺陷

匹配過於嚴謹:

一個空格致使安全狗被繞過:

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

嘗試在boundary後面加個空格或者其餘可被正常處理的字符:

boundary =---------------------------4714631421141173021852555099

Win2k3 + IIS6.0 + ASP

11

以上也能說明一個問題,安全狗在上傳文件時匹配各個參數都十分嚴謹,不過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

12

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

13

ASCII > 127的字符:

14

數據過長致使的繞過:

waf若是對Content-Disposition長度處理的不夠好的話可能會致使繞過,例如:

Win2k3 + IIS6.0 + ASP

15

基於文件名:基於構造長文件名

16
若是web程序會將filename除了擴展名的那段重命名的話,那麼還能夠構造更多的點、符號等等。

17

特殊的長文件名:
文件名使用非字母數字,好比中文等最大程度的拉長,不行的話再結合一下其餘的特性進行測試:

shell.asp;王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王.jpg

0x05 End

文件上傳Bypass可寫的點很少,現有的姿式也不能拿出來說(笑)重點在於上傳文件時遇到waf可以準確判斷所攔截的點,目光不能只盯在waf,更多的時注意後端的狀況。每每是須要結合哪些語言/容器/系統*版本「能夠怎樣」、「不能夠怎樣」。

相關文章
相關標籤/搜索