WAF的那些事

coderge發表於2020-09-26

介紹WAF

本節主要介紹WAF (Web Application Firewall, Web應用防火牆)及與其相關的知識,這裡利用國際上公認的一種說法: Web應用防火牆是通過執行系列針對HTTP/HTTPS的安全策略來專門為Web應用提供保護的一款產品。
WAF基本上可以分為以下幾類。

軟體型WAF

以軟體形式裝在所保護的伺服器上的WAF,由於安裝在伺服器上,所以可以接觸到伺服器上的檔案,直接檢測伺服器上是否存在WebShell、是否有檔案被建立等。

硬體型WAF

以硬體形式部署在鏈路中,支援多種部署方式,當串聯到鏈路中時可以攔截惡意流量,在旁路監聽模式時只記錄攻擊不進行攔截。

雲WAF

一般以反向代理的形式工作,通過配置NS記錄或CNAME記錄,使對網站的請求報文優先經過WAF主機,經過WAF主機過濾後,將認為無害的請求報文再傳送給實際網站伺服器進行請求,可以說是帶防護功能的CDN。

網站系統內建的WAF

網站系統內建的WAF也可以說是網站系統中內建的過濾,直接鑲嵌在程式碼中,相對來說自由度高,一有以下這幾種情況。

  • 輸入引數強制型別轉換(intval等) 。
  • 輸入引數合法性檢測。
  • 關鍵函式執行(SQL執行、 頁面顯示、命令執行等)前,對經過程式碼流程的輸入進行檢測。
  • 對輸入的資料進行替換過濾後再繼續執行程式碼流程(轉義/替換掉特殊字元等)網站系統內建的WAF與業務更加契合,在對安全與業務都比較瞭解的情況下,可以更少地收到誤報與漏報。

WAF判斷

介紹幾種判斷網站是否存在waf的方法。

SQLMap

python sqlmap.py -u "http://xxx.com/se/" --identify-waf --batch
使用SQLMap中自帶的WAF識別模組可以識別出WAF的種類,但是如果所安下面裝的WAF並沒有什麼特徵,SQLMap就只能識別出型別是Generic。下面以某衛士官網為例,在SQLMap中輸入以下命令,結果如圖所示。

可以看到識別出WAF的型別為XXX Web Application Firewall。要想了解詳細的識別規則可以檢視SQLMap的WAF目錄下的相關指令碼,也可以按照其格式自主新增新的WAF識別規則,寫好規則檔案後直接放到WAF目錄下即可。

手工判斷

這個也比較簡單,直接在相應網站的URL後面加上最基礎的測試語句,比如union select 1,2,3%23, 並且放在一個不存在的引數名中,本例裡使用的是引數aaa,如圖所示,觸發了WAF的防護,所以網站存在WAF。

因為這裡選取了一個不存在的引數,所以實際並不會對網站系統的執行流程造成任何影響,此時被攔截則說明存在WAF。
被攔截的表現為(增加了無影響的測試語句後) :頁面無法訪問、響應碼不同、返回與正常請求網頁時不同的結果等。

一些WAF的繞過方法

本小節主要介紹SQL隱碼攻擊漏洞的繞過方法,其餘漏洞的WAF繞過方法在原理上是差不多的。

大小寫混合

在規則匹配時只針對了特定大寫或特定小寫的情況,在實戰中可以通過混合大小寫的方式進行繞過(現在幾乎沒有這樣的情況),如下所示。

uNion sElEct 1,2,3,4,5

URL編碼

極少部分的WAF不會對普通字元進行URL解碼,如下所示。

union select 1,2,3,4,5

上述命令將被編碼為如下所示的命令。

%75%6e%69%6f%6e%20%73%65%6c%65%63%74%20%31%2c%32%2c%33%2c%34%2c%35

還有一種情況就是URL二次編碼,WAF一般只進行一次解碼,而如果目標Web系統的程式碼中進行了額外的URL解碼,即可進行繞過。

union select 1,2,3,4,5

上述命令將被編碼成如下的命令:

%2575%256e%2569%256f%256e%2520%2573%2565%256c%2565%2563%2574%2520%2531%252c%2532%252c%2533%252c%2534%252c%2535

替換關鍵字

WAF採用替換或者刪除select/union 這類敏感關鍵詞的時候,如果只匹配一次則很容易進行繞過。

union select 1,2,3,4,5

上述命令將轉換為如下所示的命令

ununionion selselectect 1,2,3,4,5

使用註釋

註釋在截斷SQL語句中用得比較多,在繞過WAF時主要使用其替代空格(/任意內容/),適用於檢測過程中沒有識別註釋或替換掉了註釋的WAF。

Union select 1, 2, 3, 4, 5

上述命令將轉換為如下所示的命令。

union/*2333*/select/*aaaa*/1, 2, 3, 4, 5

還可以使用前面章節中介紹的內聯註釋嘗試繞過WAF的檢測。

多引數請求拆分

對於多個引數拼接到同一條SQL語句中的情況,可以將注入語句分割插入。
例如請求URL時,GET參 數為如下格式。

a=[input1]&b=[input2]

將GET的引數a和引數b拼接到SQL語句中,SQL語句如下所示。

and a=[input1] and b=[input2]

這時就可以將注入語句進行拆分,如下所示。

a=union/*&b=*/select 1, 2, 3, 4

最終將引數a和引數b拼接,得到的SQL語句如下所示。

and a=union /*and b=*/select 1, 2, 3, 4

HTTP引數汙染

HTTP引數汙染是指當同一引數出現多次,不同的中介軟體會解析為不同的結果,具體如表所示(例子以引數color=red&color= blue為例)

在上述提到的中間線中,IIS比較容易利用,可以直接分割帶逗號的SQL語句。在其餘的中介軟體中,如果WAF只檢測了同引數名中的第一個或最後一個,並且中介軟體特性正好取與WAF相反的引數,則可成功繞過。下面以IIS為例,一般的SQL隱碼攻擊語句如下所示。
Inject=union select 1, 2, 3, 4
將SQL隱碼攻擊語句轉換為以下格式。
Inject=union/*&inject=*/select/*&inject=*/1&inject=2&inject=3&inject=4
最終在IIS中讀入的引數值將如下所示。
Inject=union/*,*/select/*,*/1, 2, 3, 4

生僻函式

使用生僻函式替代常見的函式,例如在報錯注入中使用polygon()函式替換常用的updatexml() 函式,如下所示。
SELECT polygon((select*from (select*from(select@@version)f)x));

尋找網站源站IP

對於具有云WAF防護的網站而言,只要找到網站的IP地址,然後通過IP訪問網站,就可以繞過雲WAF的檢測。
常見的尋找網站IP的方法有下面這幾種。

  • 尋找網站的歷史解析記錄。
  • 多個不同區域ping網站,檢視IP解析的結果。
  • 找網站的二級域名、NS、MX記錄等對應的IP。
  • 訂閱網站郵件,檢視郵件傳送方的IP。

注入引數到cookie中

某些程式設計師在程式碼中使用$_REQUEST獲取引數,而$_REQUEST會依次從GET/POST/cookie中獲取引數,如果WAF只檢測了GET/POST而沒有檢測cookie,可以將注入語句放入cookie中進行繞過。