WAF繞過的捷徑與方法
在企業架構中,安全體系同剝洋蔥一般,由外及內是由一層層的安全產品和規范構成,越處于外層承重越大,WAF 屬七層防護的第一道墻,隨著互聯網技術發展,業務對外提供服務的方式逐漸收攏,Web 接口與應用壟斷流量,WAF成了安全戰場中被炮火攻擊最慘烈的前線。
一、痼疾
雖然WAF 屬于較成熟的安全產品,但不同公司,不同場景都可能衍生出不同的部署方式,一個關鍵原因就是安全、效率、成本的不可能三角,互聯網公司中,效率代表產品的易用性和響應時間,往往很難有較大犧牲,成本和安全的組合形式決定了安全產品架構的不同,即便在傾向選擇中安全成為首位,WAF 產品本身也有痼疾:HTTP 協議和業務場景的復雜性導致很難有統一的策略規范,加之 WAF 抽離于業務代碼邏輯以外,這些耦合上的瑕疵很容易成為繞過 WAF 防護的突破口。
再者,不管是基于正則匹配還是機器學習,考量 WAF 的指標永遠是相互矛盾的:誤報率,漏報率。在安全和效率(業務)的博弈中,沒有完美,只有適配,這也就決定了 WAF 的定位。
二、WAF 繞過
WAF 的痼疾在越來越復雜的系統對接中存在耦合缺漏,不同類型的漏洞,在 WAF 的 Bypass 測試中關注點自然也不同,本文嘗試找尋一些規則對抗以外的捷徑進行 bypass,通過以下幾個維度進行嘗試:
- 架構層面
- 協議/中間件層面
- 系統/數據庫/編程語言層面
1. 架構層面
在千奇百怪的 WAF 架構中,始終脫胎換骨于兩種基礎的架構:串聯和旁路。
(1) 串聯
串聯 WAF 一般權重較高,對攻擊的請求和會話有優先于業務的一票否決權,是最為常見的 WAF 架構方式,不過串聯接入業務意味著 WAF 系統會捆綁、分擔業務指標,在日益追求高響應的復雜鏈路中強行增加了一個單點故障隱患,那考核運維健壯性的指標(可用性、響應耗時和故障率等)將是懸置 WAF 頭頂的達摩克利斯之劍。
串聯 WAF 根據產品形態又有多種變形,常見的區分方式看設備部署位置。
傳統的硬件盒子設備一般放置在網關入口后,業務中間件之前,串聯部署方式有透明模式、反向代理模式等,其前置于中間件,意味著 WAF 需預留很大一部分性能來處理 HTTP 拆解和封裝的工作,尤其是當下 HTTPS 已成為普遍場景,設備處理性能急劇下降,使得此類架構的成本投入極大。
(2) 透明連接模式:
(3) 反向代理模式:
當下云廠商最常用修改域名 CNAME 做多維安全防護的架構同硬件類部署方式在應用場景視角是一致的,不過云廠商的設備和網絡資源豐富,人才資源配備到位,又有大廠品牌背書,只要有足夠的用戶均攤成本,這種架構算在成本、效率、安全不可能三角中屬協調最優的解決方案。
(4) CNAME 架構:
對于此類前置串聯架構的 ByPass 測試需找尋 WAF 與中間件、后端業務間的耦合性缺漏,比如:
- 在使用了 SSL 套接字的會話中,協商加密算法屬請求方可控,WAF 和后端業務在算法支持上可能存在差異的一個切入點,遍歷后端業務支持但 WAF 不支持的加密算法,便可直接繞過 WAF 了,相關工具見 Github:https://github.com/LandGrey/abuse-ssl-bypass-waf
SSL Bypass
- 針對 CNAME 方式接入 WAF 的系統,能否繞過的關鍵在于后端的業務配置是否嚴謹,如果后端業務未限制訪問源,很容易通過域名解析歷史和 [ 大規模的掃描 ] 定位到真實的 IP 地址,修改本地 HOST 便可以繞過 WAF 直接對后端系統進行攻擊;
- WAF 與中間件的耦合缺漏在后續的中間件層面做詳細講解,此處不做贅述。
還有另一類串聯的部署方式,即 WAF 設備位置后移,嵌套到中間件上,這樣 WAF 的損耗將分攤到業務機器,這樣的捆綁意味著一榮俱榮,一損皆損,又因位置后移到了業務側,策略下發和管理都極其復雜,且中間件種類繁多,規模一大,這種架構堪稱災難,而隨著業務架構的逐漸優化,一般的互聯網業務架構會前置越來越輕的轉發層,將 WAF 嵌到轉發層,或在轉發層通過 openresty 等方式將請求過一遍旁掛的 WAF 集群,這屬對業務鏈路侵入最輕的一種方式,很多互聯網公司自建的 WAF 采用該架構。
(5) 中間件部署:
(6) OpenResty 部署:
對于此類嵌套于中間件的 WAF 架構測試需針對 WAF 模塊的系統耗能和超時為切入點,當中間件或 WAF 模塊達到一定的性能損耗指標,一般 WAF 系統會預留類似硬件設備斷電 bypass 的功能來保障業務可用性的強指標,通過這種途徑即可突破 WAF,比如:
- 針對中間件本身的漏洞(例如: CVE-2018-1336 )/配置錯誤來觸發 DOS,當系統能耗達到閾值,自動關閉 WAF 模塊;
- 針對 WAF 系統的正則策略進行攻擊,通過 ReDoS:https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS
使策略檢測超時,單條會話跳過 WAF 集群響應,直接通聯后端業務。
(7) 旁路
旁掛 WAF 一般不在會話鏈路以內,這意味著針對命令執行、Getshell 類的一條語句拿權限的攻擊束手無策,滿足業務性能,犧牲了較多的安全指標,做出這種妥協,一方面是業務/運維強勢,可用性是相關部門較重的 KPI 指標,另一方面可能是 WAF 系統開發和運營人力資源緊張,旁路離線分析提供了一定的緩和空間。
旁路 WAF 可以理解為一套離線分析系統,在各類配置和參數設置上很難同業務機器同步,這導致兩者之間的耦合缺漏會更大,且旁路部署的后置阻斷措施也極具多樣性:IP 維度(4 層封禁、7 封封禁),session 維度(業務路由基于登陸的 cookies 等),給繞過也提供了一些方法,常見的繞過方法有:
- 若系統是通過分光等方式旁掛,那針對前置串聯 WAF 的 SSL 證書繞過方法在這里一樣通用;
- 通過攻擊測試,很容易判斷出旁路 WAF 同阻斷組件的通聯時間,獲取海量且廉價的代理 IP,控制好單 IP 的測試存活時間,較低成本便可繞過;
- 針對異常協議和中間件特效的攻擊將在后續章節講述,在旁掛 WAF 上均可實現繞過。
WAF 產品架構多樣,除了串聯和旁路外,基于業務特性還有各種各樣的組合方式,之前所在公司基于業務架構單一的特點(系統、語言、中間件、數據庫版本等相關信息全局一致),只需要關注固定版本的系統/應用漏洞情報,便可采用平日旁掛,漏洞爆發打開串聯開關,漏洞批量修復后恢復旁掛的方式,在安全、效率、成本的博弈中發揮一點能動性。
2. 協議/中間件層面
HTTP 協議是一個漸進工程。
1991 初版草案 (HTTP/0.9) 僅有不足一頁半的內容,在經歷 5 年時間和若干版本的更替后,第一個正式版 HTTP/1.0 標準誕生,這時它已經變成一份密密麻麻長達 50 頁的文檔,期望能彌補過往標準里的諸多缺陷。很快到了 1999 年,HTTP/1.1 的 7 位署名作者顯然指望該協議能涵蓋到方方面面,導致的結果就是一份長達 150 頁的大作。但這些越來越宏偉的文檔里很大篇幅的內容和我們當下實際使用的 Web 并不特別相關,因為他們對新功能的追逐比修復舊有缺陷更感興趣。
—— 《Web 之困》 |
處于尚未完結的漸進工程中,強制的向下兼容,加之各類中間件對協議的解讀和實現花樣百出,導致整個協議骨干健壯清晰,細枝末節處卻錯綜繁雜,越是復雜有異議的地方,越是存在安全隱患。
如《Web 之困》書中所描述,協議版本的升級,大多數精力都投入到了新花樣和動人功能的開發上,缺陷的修補向來是不受人待見的,而協議側的缺陷卻往往是致命的。
DEFCON 24 會議上,regilero 有一篇名為《Hiding Wookiees In Http》的演講,詳細分析了 HTTP 協議中 Keepalives 和 Pipelines 組合使用上的缺漏,可導致會話注入和緩存投毒,在 WAF 繞過上也提供了一條路徑。
Keepalives 雖然在 HTTP1.0 版本便可以使用,但并沒有得到官方的確認,是瀏覽器爆炸發展階段的民間戰勝官方的勝利,HTTP1.1 版本后才開始作為默認參數參與到請求中,這條參數也屬于新版本令人心動的嶄新功能,引入的原因也是為了解決請求量級斗升,新建立連接帶來的系統和網絡損耗,功能大致如下所示:
(1) HTTP Pipeline:
(2) HTTP KeepAlive:
(3) HTTP 1.0:
功能設計本身的意圖是多請求單連接,但‘多請求’這個場景又有多般演繹,比如下圖這種請求,在 WAF 端的識別上,這屬于一個請求,邏輯也是通過拆解 Key、value 的模式以 Body 內容讀取第二個請求的內容,當然是屬于異常的 Key-Value 結構,這樣第二個包的內容便很容易繞過 WAF 策略直接進行攻擊了。
(4) Keeplive 繞過:
關于 HTTP 協議特性的安全缺陷,還有一個值得說道的漏洞,2011 年 BlackHat 大會有一篇名為《Checkmate with Denial of Service》的演講,闡述了一系列 DOS 漏洞,其中有部分是關于 HTTP 慢速攻擊的分析,此后漫長的一段時間中,slowloris 都是諸多大型 DDOS 事件中的主角,關于慢速 DOS 的原理其實就是利用了 HTTP 的特性,通過 Keepalives 特性,發起大量請求,修改 Content-Length,Hold 住會話,在超時前定期發送小包,保持存活狀態,使服務端線程數打滿,又不得釋放,服務便處于不可用狀態,這種攻擊在前文所述的針對中間件的 DOS 中不失為一種有效的攻擊繞過方式。
除了協議特性以外,異變的 HTTP header 也有可能提供繞過 WAF 的捷徑,2018 年的 AppSec 大會上,有一篇《hacker WAF bypass techniques》的演講,通過以下幾個方式進行 WAF 繞過:
- 字符集編碼;Content-Type 頭中使用 charset 定義字符集的應用場景不只有在 responses 中,request 中同樣可以使用,而變換字符編碼集以后,基于規則引擎的 WAF 則徹底失控。
- 內容類型格式;在特定中間件版本下 Key-value 可以通過文件上傳的類型 multipart/form-data 進行提交,而 WAF 針對此類型側檢測一般是只針對上傳漏洞,導致常規的 xss、sqli 便可以通過該方式進行 bypass,即使存在各通用類型的漏洞檢測,也可通過 Fuzz 異變上傳類型的格式,達到 WAF 無法識別,后端中間件可以解析的目的:
當然以上 Bypass 的路徑并非通用的,很大情況與不同中間件對 HTTP 的理解和運用有關,詳細中間件系統和版本測試情況可參見表格:
https://drive.google.com/file/d/0B5Tqp73kQStQU1diV1Y0dzd1QU0/view
基于協議/中間件的安全缺陷并不全然是功能帶來的,有時帶業務特性的配置也會有缺漏,且這種缺漏是前端 WAF 和后端業務中間件功能差異所必然存在的,也是大多數通用 WAF 產品很難和業務適配的死角,突出的例子如:
請求包大小限制;很多后端業務存在上傳功能,所以請求數據限制上往往會較大,而前置 WAF 系統,需要有較高的響應時間,請求包較大時往往超過內置的性能和耗時閾值,所以可直接發送大量無意義的參數,尾端帶攻擊參數便可直接繞過 WAF 系統。
3. 系統/數據庫/編程語言層面
系統、數據庫和編程語言層面,屬于對抗 WAF 策略的正面戰場,這類文章網上佳作不勝枚舉,但其達成繞過的功效并不具通用性,比如系統級別的繞過可能圍繞命令執行、LFI 之類的漏洞,數據庫相關的繞過是圍繞 Sqli 類漏洞,且兩者的繞過思路大致相同,即利用系統/數據庫特性或不常用函數繞過 WAF 策略特征,至于編程語言的繞過方式則相對靈活,這也是動態語言的特性決定的,本文主旨是 WAF 繞過的捷徑,正面對抗策略內容便不多做贅述(正面硬剛 WAF 規則也有成熟工具,詳細內容參見參考文檔中 2016 blackhat 大會上的《Another Brick off The Wall: Deconstructing Web Application Firewalls Using Automata Learning》一文),每個類型各介紹一類比較有代表性的 Bypass 方法:
- 系統層面,利用 Linux 通配符特性繞過 WAF 策略;在 bash 語法中,可以使用與系統文件相同數量的 "?", "/" 來匹配該文件;用未初始化的變量隔離特征字符;用 ' 字符拆解再拼貼,繞過字符匹配。
- 數據庫層面,利用 mysql 注釋和注釋特性繞過 WAF 策略;在 ModSecurity (最常見的開源 WAF 框架)默認策略中,union select 這類 Sqli 注入語法一般是貪婪匹配 union 和 select 之間的字符、數字、下劃線、左括號,很容易通過插入 /* */注釋繞過;當變更規則過濾掉注釋,依然可以通過在注釋中使用 ! 加版本號包裹關鍵詞來繞過檢測,因為只要 mysql 的當前版本等于或大于該版本號,則該注釋中的 sql 語句將被 mysql 執行;
- 編程語言層面,利用 PHP 數組特性繞過 WAF 策略;在 PHP 中每個字符串都可以當作數組,這樣基于字符串的正則匹配就很容易被繞過了。
限于文章篇幅,簡單描述了 WAF Bypass 測試的整體框架,相當一部分繞過方法未能展示,由于議題寬泛,時間緊迫,故倉促收尾,算理清框架脈絡,避免后來者按圖索驥的浪費時間。
參考文檔
- Abuse-ssl-bypass-waf:https://github.com/LandGrey/abuse-ssl-bypass-waf
- Bypassing Web-Application Firewalls by abusing SSL/TLS:https://0x09al.github.io/waf/bypass/ssl/2018/07/02/web-application-firewall-bypass.html
- WAF Bypass Techniques - Using HTTP Standard and Web Servers’ Behaviour:https://www.slideshare.net/SoroushDalili/waf-bypass-techniques-using-http-standard-and-web-servers-behaviour
基于 Openresty 的云 WAF 工作原理:
- https://www.yqfy.net/base-on-openresty-waf
- Regular expression Denial of Service - ReDoS:https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS
《Web之困》:
- https://book.douban.com/subject/25733421/
- DEFCON 24 《Hiding Wookiees In Http》:https://media.defcon.org/DEF%20CON%2024/DEF%20CON%2024%20presentations/DEFCON-24-Regilero-Hiding-Wookiees-In-Http.pdf
- Checkmate with Denial of Service:https://media.blackhat.com/bh-dc-11/Brennan/BlackHat_DC_2011_Brennan_Denial_Service-Slides.pdf
- Web Application Firewall (WAF) Evasion Techniques:https://medium.com/secjuice/waf-evasion-techniques-718026d693d8
- Web Application Firewall (WAF) Evasion Techniques #2:https://medium.com/secjuice/web-application-firewall-waf-evasion-techniques-2-125995f3e7b0
- Web Application Firewall (WAF) Evasion Techniques #3:https://www.secjuice.com/web-application-firewall-waf-evasion/
- Another Brick off The Wall: Deconstructing Web Application Firewalls Using Automata Learning:https://www.blackhat.com/docs/eu-16/materials/eu-16-Argyros-Another-Brick-Off-The-Wall-Deconstructing-Web-Application-Firewalls-Using-Automata-Learning.pdf