作者:vivo 網際網路安全團隊- Gui Mingcheng
本文介紹了兩種攻擊者無需直接接觸服務端即可攻擊和影響使用者行為的安全漏洞 —— Web快取汙染與請求走私。Web快取汙染旨在透過攻擊者向快取伺服器投遞惡意快取內容,使得使用者返回響應結果而觸發安全風險。HTTP請求走私旨在基於前置伺服器(CDN、反向代理等)與後置伺服器對使用者請求體的長度判斷標準不一致的特性,構造能夠被同一TCP連線中其它使用者夾帶部分惡意內容的攻擊請求,從而篡改了受害者的請求與響應行為。兩種漏洞均需要透過針對中介軟體的合理配置與業務介面的合理設計進行排查和防禦。
一、Web 快取汙染攻擊原理與場景
1.1 什麼是快取?
快取技術旨在透過減少延遲來加速頁面載入,還可以減少應用程式伺服器上的負載。一些公司使用像Varnish這樣的軟體來託管他們自己的快取,而其他公司選擇依賴像Cloudflare這樣的內容分發網路(CDN),快取分佈在世界各地。此外,一些流行的Web應用程式和框架(如Drupal)具有內建快取。Web快取汙染關注的是CDN等前置服務端部署的快取服務,還有其他型別的快取,例如客戶端瀏覽器快取和DNS快取,但它們不是本次研究的關注點。
1.2 快取的工作機制?
由CDN等代理層伺服器根據“快取鍵”快取使用者請求對應的響應,並在某個請求再次到來時直接返回相應的響應包。例如如下場景中,紅色字型標識了快取伺服器配置的快取鍵內容,A使用者訪問服務端返回的結果後,B使用者再次訪問僅會取得快取伺服器中的內容,因為快取伺服器認為兩者是同一個請求,無需再向業務服務端重新請求一次。
1.3 快取汙染具體是如何實現的?
當攻擊者的請求中,快取鍵和普通使用者沒有差別,而請求中其它部分存在可體現在響應包中的惡意內容或程式碼時,該響應被快取後,其它請求了同一個正常快取鍵對應介面的使用者會直接得到攻擊者提前交給快取伺服器快取的惡意響應。
以下是一個簡單的例子,業務某個介面存在邏輯:獲取使用者請求Host頭的內容,拼接至響應包的js連結中作為訪問域名。此時攻擊者注入惡意域名hack.com,受害者訪問快取資源的時候得到的是和攻擊者一樣的響應結果。此時攻擊者透過JavaScript程式碼幾乎劫持了受害者在前端的所有資訊和行為,具體的後果則由其中的惡意程式碼所決定,這與XSS的攻擊後果是類似的。
Web快取能夠構造什麼樣的攻擊,取決於在不破壞快取鍵的同時,構造能夠在響應中體現惡意行為的請求,例如業務邏輯對Host頭中的值進行校驗和請求,但沒有校驗埠號是否為443或80。此時可以構造請求使得響應跳轉至1337埠,其它受害者對該介面的訪問便不再可用:
擴充學習 —— 攻擊者如何確定快取鍵的覆蓋範圍?
首先需要確認是否存在快取鍵:
- HTTP頭直接返回快取的相關資訊
- 觀察動態內容的變化
- 返回時間的差異
- 特定的第三方快取配置頭
如何定位快取鍵的覆蓋範圍:
- 對請求A改動一處成為請求B,各自響應有所差異。若請求B後得到A的快取結果,則說明A、B的快取鍵相同,也說明了改動之處並非快取鍵。
- 改變請求A某處內容傳送,響應cache頭仍然在快取計時,說明該處內容部分不為快取鍵。反之,重新命中,則該處內容包含快取鍵。
- 利用特定的頭來查詢快取鍵,例如:Pragma: akamai-x-get-cache-key, akamai-x-get-true-cache-key。
二、Web快取汙染防禦手段
2.1 禁用快取配置
對快取投毒的最強大防禦辦法就是禁用快取。
對於一些人來說,這顯然是不切實際的建議,但我推測很多網站開始使用Cloudflare等服務的目的是進行DDoS保護或簡化SSL的過程,結果就是容易受到快取投毒的影響,因為預設情況下快取是啟動的。如果對確定哪些內容是“靜態”的足夠確認,那麼只對純靜態的響應進行快取也是有效的。
2.2 避免從請求中直接獲取輸入放在響應中
一旦在應用程式中識別出非快取鍵的輸入,理想的解決方案就是徹底禁用它們。如果不能實現的話可以在快取層中剝離該輸入,或將它們新增到快取鍵。建議使用Param Miner等審計應用程式的每個頁面以清除非快取鍵的輸入。
三、HTTP請求走私攻擊原理與場景
3.1 HTTP請求走私的基本原理
在RFC2616的第4.4節中,規定:如果收到同時存在Content-Length和Transfer-Encoding這兩個請求頭的請求包時,在處理的時候必須忽略Content-Length。但實際處理往往沒有遵守該協議。HTTP請求的開頭與結束標誌可以透過Content-Length來決定,也可以透過宣告的Transfer-Encoding: chunked對HTTP分組來決定。當前置伺服器和後置伺服器對HTTP請求開頭和結束標誌的判斷處理標準不一致時,就可能導致攻擊者前一個請求的後半部分在後置被認為是下一個請求的開頭,從而出現HTTP走私漏洞。
根據前後置伺服器的不同請求體長度判斷組合模式,有以下攻擊場景:
本質原因:
- 前後置伺服器對請求體長度的判斷標準存在Content-Length和Transfer-Encoding兩種形式
- 前置伺服器和後置伺服器之間存在TCP連線重用,混雜多個使用者的請求
3.2 Content-Length和Transfer-Encoding請求頭如何制定請求體長度?
請求體中每個字元為一個位元組的長度,換行符包含 \r 和 \n 兩個位元組長度,Content-Length標識請求體從開頭到最後一個字元的總長度:
- Content-Length
POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
q=smuggling
請求體中每個字元為一個位元組的長度,換行符包含 \r 和 \n 兩個位元組長度。每段請求內容分別由一行16進位制長度值和一行內容本身所組成,例如“q=smuggling”長度為11(16進位制:b),“q=smuggle”長度為9(16進位制:9)。內容結束後,以 0 和兩個換行符結束請求體:
- Transfer-Encoding: chunked
POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded Transfer-Encoding: chunked
b
q=smuggling
9
q=smuggle
0
[\r\n]
[\r\n]
3.3 HTTP請求走私如何攻擊?
基於上面描述的5種前後置伺服器不同的請求體長度判斷模式,這裡抽選其中的 CL-TE 和 TE-CL 模式進行舉例:
- CL - TE
此時,業務前置伺服器取使用者請求頭中Content-Length的值為長度判斷標準,後置伺服器根據Transfer-Encoding: chunked解析請求體來判斷請求體長度。
如下所示,攻擊者構造的請求,前置伺服器認為有6個字元,包含了 0 和兩個換行 以及 G。而後置伺服器則根據Transfer-Encoding: chunked解析請求體,認為 0 和兩個換行符已經是請求的結束標誌,字元G被滯留在了TCP管道中。
此時同一個TCP連線中中,一個受害者的請求接踵而至,後置伺服器便會將字元G拼接至其請求開頭,從而使得受害者實際對業務請求了GGET方法。
- TE - CL
與CL - TE類似,前置伺服器先根據Transfer-Encoding: chunked放行攻擊者的整個請求體,經過後置伺服器對Content-Length的判斷,分割前半部分請求體給業務服務端,後半部分由受害者承接。
可以看到,這裡攻擊者完全可以劫持受害者的請求,從介面地址到請求頭以及請求引數,因此具有較大的危害性。
3.4 HTTP請求走私攻擊的效果是什麼?
這裡舉一個例子 —— 捕獲其他使用者的請求。攻擊者發現業務存在HTTP請求走私漏洞,同時又找到了評論介面 /post/comment 這種可以回顯請求內容的功能點。那麼攻擊者就可以走私一個 /post/comment 的評論請求,從而讓受害者“被迫”以這個請求去訪問服務端。受害者的請求則被拼接到評論請求中的comment引數後,作為請求內容而出現。
攻擊者去檢視評論區,發現受害者已經將自己先前的請求(連同Cookie等資訊)一併傳送到了評論區。
踩坑記錄
這裡受害者的請求中一旦出現 “&” 字元,就會被當做 POST BODY的引數分隔符從而中止comment評論內容引數的解析。因此評論區僅能看到受害者請求中第一個 “&” 字元之前的內容。
四、HTTP請求走私防禦手段
4.1 通用防禦措施
- 禁用代理伺服器與後端伺服器之間的TCP連線重用。
- 使用HTTP/2能夠避免請求邊界判定標準不一致的問題。
- 前後置伺服器使用同樣的web伺服器程式,保證對請求邊界的判斷標準是一致的。
4.2 實際問題
以上的措施有的不能從根本上解決問題,而且有著很多不足,就比如禁用代理伺服器和後端伺服器之間的TCP連線重用,會增大後端伺服器的壓力。使用HTTP/2在現在的網路條件下根本無法推廣使用,哪怕支援HTTP/2協議的伺服器也會相容HTTP/1.1。從本質上來說,HTTP請求走私出現的原因並不是協議設計的問題,而是不同伺服器實現的問題。因此要嚴格保證前後置伺服器對請求邊界的判斷標準是一致的來防護該型別風險的出現。
五、實戰演示
六、總結
Web快取汙染和HTTP請求走私是兩種不太被關注到、但影響力和危害較大的兩種安全漏洞型別。其共同點是均脫離業務應用本身,依託於嚴格規範的運維、網路人員的相關配置,因此在出現問題時對業務邏輯本身的排查往往會偏離實際情況。
Web快取汙染能夠使攻擊者批次影響共用了同一快取資源的所有使用者,HTTP請求走私能夠使得攻擊者隨機在長連線中影響其他同時訪問業務使用者的請求內容,實際造成的影響取決於存在漏洞的介面和業務本身提供了多少能夠利用的許可權和功能。
因此,如果說有哪種漏洞能夠在不直接攻擊業務伺服器和受害者電腦就能夠實施大批次的攻擊利用,從而影響到使用者請求和收到的響應內容,則Web快取汙染和HTTP請求走私會是我們重點關注的核心風險問題。