HTTP繞WAF之淺嘗輒止
0X00前言
最近參加重保,和同事閑聊時(shí)間,談起來了外網(wǎng),彼時(shí)信心滿滿,好歹我也是學(xué)了幾年,會(huì)不少的。結(jié)果,扭頭看完do9gy師傅的《騰訊 WAF 挑戰(zhàn)賽回憶錄》,就啪啪打臉了。說來慚愧,最近一段時(shí)間,拿到offer就開始飄起來了,現(xiàn)在悔不當(dāng)初,于是就想寫一篇關(guān)于這篇Http首部字段文章的"訓(xùn)詁篇"出來,一來當(dāng)做知識(shí)鞏固,二來算是完善些和首部字段相關(guān)的知識(shí)點(diǎn)(可會(huì)因?yàn)橐娮R(shí)不足,導(dǎo)致遺漏)。畢竟,小白可能這方面了解不多,只了解Cookie和Agent這種常見類型的首部字段,卻很少聽過Accept-Encoding和Content-Encoding這類不太常用的首字部。
0X01基礎(chǔ)知識(shí)
關(guān)于WAF的問題?
它是我們?nèi)粘9シ姥菥毐貢?huì)遇見的,在IOS七層模型中,WAF分為網(wǎng)絡(luò)層、應(yīng)用層的,當(dāng)然還有云 WAF(CDN+WAF)這新型類場(chǎng)景的。不同環(huán)境下我們繞過WAF的思路也是有所區(qū)別的,例如,對(duì)于傳統(tǒng)的網(wǎng)絡(luò)層 WAF,采用chunked編碼(即對(duì)內(nèi)容進(jìn)行所謂的"加密")即可繞過,下次遇見的時(shí)候,我們?nèi)匀粐L試在網(wǎng)絡(luò)層這一類型上進(jìn)行嘗試和探索。
存在于應(yīng)用層的WAF,它們的處理引擎是經(jīng)過前端到達(dá)Apache(或者是Nginx)完成 HTTP協(xié)議初步解析后,再轉(zhuǎn)交給引擎處理的,這個(gè)時(shí)候網(wǎng)絡(luò)層的繞過技術(shù)是無效的。這就需要我們?nèi)パ芯浚簩?duì)于一個(gè) HTTP 請(qǐng)求,Nginx 解析了什么內(nèi)容?交給后面的 PHP、ASP 又解析了什么內(nèi)容?(探究到這個(gè)深度,就需要有良好的編程基礎(chǔ)和協(xié)議基礎(chǔ),否則,后面及其吃力)。
至于最后的云WAF,我們可以簡(jiǎn)單的看成CDN加上軟件WAF的結(jié)合體,既可以抗住DDos攻擊,也可以過濾出部分簡(jiǎn)單的Payload攻擊代碼,甚至對(duì)流量也有一定的清洗作用。
HTTP首部的利用方式?
HTTP 請(qǐng)求頭Content-Type的charset編碼可以指定內(nèi)容編碼,在國(guó)內(nèi)大多數(shù)都是UTF-8編碼,但是攻擊者在攻擊的時(shí)候可以替換為 ibm037、 ibm500、cp875等不常用的"偏門"編碼來繞過WAF的檢測(cè)。我們也可以通過設(shè)置Content-Type頭的值為application/x-www-form或者multipart/form-data;charset=ibm500,boundary=blah等進(jìn)行繞過。
0X02首字部Encoding
關(guān)于Encoding,整個(gè)名稱應(yīng)該為Accept-Encoding;它在http協(xié)議中的作用是可以對(duì)內(nèi)容(也就是body部分)進(jìn)行編碼。Accept-Encoding: gzip:表示它可以采用gzip這樣的編碼,從而達(dá)到壓縮的目的。這樣的話關(guān)于網(wǎng)絡(luò)層的WAF是可以被繞過的,當(dāng)然我們也可以使用其他的編碼把內(nèi)容攪亂或加密,以此來防止未授權(quán)的第三方看到文檔的內(nèi)容。當(dāng)服務(wù)端接收到請(qǐng)求,并且從Header里拿到編碼標(biāo)識(shí)時(shí),就可以選擇其中一種方式來進(jìn)行編碼壓縮,然后返給客戶端。
瀏覽器發(fā)給服務(wù)器,聲明瀏覽器(客戶端)支持的編碼類型解釋
Accept-Encoding設(shè)置在請(qǐng)求頭當(dāng)中,會(huì)告訴服務(wù)器,我可以接受哪種編碼壓縮
Content-Encoding設(shè)置在響應(yīng)頭中,會(huì)告訴客戶端,我用的是哪種編碼壓縮
?小提示:Encoding?的大概意思是:決定文件接收方將以什么形式、什么編碼讀取這個(gè)文件,指定服務(wù)器響應(yīng)的 HTTP 內(nèi)容類型;這兩個(gè)header頭都會(huì)影響服務(wù)器對(duì)于數(shù)據(jù)內(nèi)容的傳輸格式類型(壓縮算法);文章:參考鏈接!
小提示:Accept-Encoding: deflate?但發(fā)現(xiàn)這種方法已經(jīng)過時(shí)了,我們可以換成Accept-Encoding: gzip,發(fā)現(xiàn)上傳成功。
加密繞過
分塊傳輸繞過
如果在HTTP首字部中加入Transfer-Encoding: chunked。我們就可以利用這個(gè)報(bào)文采用了分塊編碼的方式繞過應(yīng)用層面的WAF。原因的這時(shí)是通過POST請(qǐng)求報(bào)文中的數(shù)據(jù)部分,并對(duì)數(shù)據(jù)進(jìn)行分塊傳輸。每個(gè)分塊包含十六進(jìn)制的長(zhǎng)度值和數(shù)據(jù),長(zhǎng)度值獨(dú)占一行,長(zhǎng)度不包括它結(jié)尾的,也不包括分塊數(shù)據(jù)結(jié)尾的,且最后需要用0獨(dú)占一行表示結(jié)束(同時(shí)末尾需要以兩個(gè)換行結(jié)束)。
小提示:上傳失敗的原因是沒有分好考?jí)K,這種可以在繞過SQL注入或者XSS的時(shí)候進(jìn)行嘗試,不建議和上圖一樣對(duì)圖片馬進(jìn)行嘗試(關(guān)鍵是不好分塊,效率低下)。
0X03首字部Pipeline
眾所周知,HTTP協(xié)議是由TCP協(xié)議封裝而來,當(dāng)瀏覽器發(fā)起一個(gè)HTTP請(qǐng)求時(shí),瀏覽器先與服務(wù)器通過TCP協(xié)議建立連接,然后發(fā)送HTTP 數(shù)據(jù)包給它,但是這里包含了一個(gè)Connection的字段,正常情況下該段的值為close。而且Apache等Web容器會(huì)根據(jù)這個(gè)字段決定是保持該 TCP 連接或是斷開。當(dāng)發(fā)送的內(nèi)容太大,超過一個(gè) HTTP 包容量,需要分多次發(fā)送時(shí),值會(huì)變成keep-alive,即本次發(fā)起的 HTTP 請(qǐng)求所建立的TCP連接不斷開,直到所發(fā)送內(nèi)容結(jié)束Connection為close時(shí)停止。
0X04首字部Disposition
Content-Disposition的具體原理:它是WAF的一個(gè)規(guī)則,針對(duì)文件上傳主要是對(duì)那個(gè)地方去做防護(hù)的,所以需要混淆去繞過?。。?/p>
由于該協(xié)議對(duì) PHP 對(duì)解析存在缺陷、使得如果一行有多個(gè) filename 字段值,則PHP構(gòu)造的Web Server會(huì)取最后的filename值進(jìn)行解析。Web Server最終可以得到的文件名是1.php,但是某些WAF只會(huì)判新第一個(gè)filename的值,因此 WAF 對(duì)上傳的文件的過濾檢測(cè)功能會(huì)被黑客繞過,并且這里的form-data是可有可無的類型,就是去掉它也不會(huì)影響Web Server獲取filename的名稱(如下所示):
雖是如此,但filename的編碼還會(huì)被HTTP請(qǐng)求Content-Type頭中charset所影響;Web Server可以根據(jù)這個(gè)值進(jìn)行響應(yīng)的解碼處理。這些都有可能被一些人稍微做點(diǎn)手腳,便可以繞過不少WAF的文件上傳過濾檢測(cè)。可能有的師傅會(huì)說,那怎么測(cè)試?。窟@個(gè)其實(shí)就見仁見智了,我通常會(huì)自己搭建一個(gè)環(huán)境進(jìn)行Fuzzing字典的黑盒測(cè)試;如果是代碼審計(jì)和CTF功底好的師傅,可能就直接測(cè)試一些漏洞點(diǎn)了。所以,這方面大家可以多看看,其他師傅寫的文章,平時(shí)多學(xué)習(xí)多做筆記了。
0X05首字部Typer
Content-Type:一般是指網(wǎng)頁(yè)中存在的Content-Type,用于定義網(wǎng)絡(luò)文件的類型和網(wǎng)頁(yè)的編碼,決定文件接收方將以什么形式、什么編碼讀取這個(gè)文件,這就是經(jīng)??吹揭恍〢sp網(wǎng)頁(yè)點(diǎn)擊的結(jié)果卻是下載到的一個(gè)文件或一張圖片的原因。
特殊編碼繞過
HTTP頭里的Content-Type請(qǐng)求頭一般有application/x-www-form-urlencoded,multipart/form-data,text/plain三種,其中multipart/form-data表示數(shù)據(jù)被編碼為一條消息,頁(yè)上的每個(gè)控件對(duì)應(yīng)消息中的一個(gè)部分。當(dāng) WAF 沒有規(guī)則匹配該協(xié)議傳輸?shù)臄?shù)據(jù)時(shí)則可被繞過。
利用特殊編碼對(duì)payload進(jìn)行轉(zhuǎn)義,從而繞過WAF對(duì)特殊關(guān)鍵詞的過濾。該方法的思路主要圍繞: multipart/form-data進(jìn)行,主要針對(duì)于 POST 參數(shù)的,對(duì)于需要在GET參數(shù)位置觸發(fā)的惡意漏洞影響不大。說起multipart/form-data 的作用,我們知道HTTP 協(xié)議POST請(qǐng)求,除了常規(guī)的 application/x-www-form-urlencoded 以外,還有 multipart/form-data 這種形式,就是為了解決上傳文件場(chǎng)景的問題下文件內(nèi)容較大且內(nèi)置字符不可控的問題而準(zhǔn)備的。multipart/form-data 格式也是可以傳遞POST參數(shù)的。對(duì)于Nginx+PHP的架構(gòu),Nginx 實(shí)際上是不負(fù)責(zé)解析 multipart/form-data 的 body 部分的,而是交由 PHP 來解析,因此 WAF 所獲取的內(nèi)容就很有可能與后端的 PHP 發(fā)生不一致。
以 PHP 為例,我們寫一個(gè)簡(jiǎn)單的測(cè)試腳本:
雙寫上傳描述行繞過
雙寫整個(gè)Part開頭繞過
構(gòu)造假的Part繞過
雙寫B(tài)oundary繞過
構(gòu)造空Boundary繞過
構(gòu)造空格+Boundary繞過
雙寫Content-Type繞過
Boundary+逗號(hào)繞過
小提示:Bypass WAF 的核心思想在于,一些 WAF 產(chǎn)品處于降低誤報(bào)考慮,對(duì)用戶上傳文件的內(nèi)容不做匹配,直接放行。事實(shí)上,這些內(nèi)容在絕大多數(shù)場(chǎng)景也無法引起攻擊。但關(guān)鍵問題在于,WAF 能否準(zhǔn)確有效識(shí)別出哪些內(nèi)容是傳給$POST 數(shù)組的,哪些傳給$FILES 數(shù)組?如果不能,那我們是否就可以想辦法讓 WAF 以為我們是在上傳文件,而實(shí)際上卻是在 POST一個(gè)參數(shù),這個(gè)參數(shù)可以是命令注入、SQL 注入、SSRF 等任意的一種攻擊,這樣就實(shí)現(xiàn)了通用 WAF Bypass。
0X06首字部Filename
截?cái)郌ilename繞過
首先將原始的帶有臟數(shù)據(jù)的 payload 轉(zhuǎn)換成文件上傳包格式的協(xié)議:multipart/form-data,然后進(jìn)行截?cái)?,如下圖所示:
以上環(huán)境并未演示到另外一種基于 HTTP 協(xié)議特性繞過 WAF 的方法(實(shí)際上是基于 “協(xié)議未覆蓋繞過” 方法,屬于它的升級(jí)改造版)——filename 文件名混淆繞過。下面直接看漏洞銀行大佬在視頻中的實(shí)戰(zhàn)利用演示。
空格+filename繞過
為了讓 Payload 能夠順利解析,可以在 fliename="1.jpg"的等號(hào)前面添加空格,讓 fliename 文件名無法解析,從而使得后面的php參數(shù)可被服務(wù)器解析執(zhí)行,最終達(dá)到繞過 WAF 同時(shí)執(zhí)行 pqyload 注入的目的:
雙引號(hào)+filename繞過
另外此處也可以在 filename 前方添加雙引號(hào),也可以實(shí)現(xiàn)上述執(zhí)行 payload 的目的:
0X07小結(jié)
通過上述學(xué)習(xí),我們知道了關(guān)于HTTP首字部的一些知識(shí)點(diǎn),進(jìn)而通過利用該首字部的特點(diǎn)進(jìn)行Fuzzing,最終達(dá)到繞過WAF的目的。當(dāng)然上述結(jié)論難免存在不足,希望師傅們斧正。經(jīng)過這幾天的資料查找,我發(fā)現(xiàn)這些東西在CTF領(lǐng)域的研究,以及達(dá)到了登峰造極的地步。而且我們真正的去理解這些東西,可能需要掌握好一門語言和對(duì)HTTP協(xié)議有所了解(導(dǎo)致我的解釋可能過于牽強(qiáng)dog),希望大家不要介意!
參考鏈接:
https://www.freebuf.com/news/193659.html
https://www.cnblogs.com/zzjdbk/p/13936278.html
https://github.com/LandGrey/abuse-ssl-bypass-waf
https://hakin9.org/bypassing-wafs-with-wafninja-free-course-content/
https://hacken.io/discover/how-to-bypass-waf-hackenproof-cheat-sheet/
https://www.notsoshant.io/blog/bypassing-waf-by-playing-with-parameters/
https://infosecwriteups.com/waf-bypasses-tearing-down-the-wall-d08fd0f8374a