【网络安全】针对 HTTP/2 协议的HTTP Desync攻击
本文將介紹攻擊者是利用漏洞發起HTTP Desync攻擊的,目標都是一些知名網站,這些漏洞通過劫持客戶端、木馬化緩存、還有竊取憑據來發起攻擊。
對Netflix的HTTP Desync攻擊
由于HTTP/2的數據幀長度字段,Content-Length標頭是不需要的。然而,HTTP/2 RFC聲明該標頭是允許的,只要它是正確的。Netflix使用了一個無需驗證內容長度就執行HTTP降級的前端。研究人員發出了以下HTTP/2請求:
在前端將此請求降級為HTTP/1.1后,它到達后端,看起來像這樣:
由于 Content-Length 不正確,后端提前停止處理請求,橙色數據被視為另一個請求的開始。這使研究人員能夠為下一個請求添加任意前綴,而不管它是誰發送的。
將受害者的請求重定向到研究人員的服務器 02.rs:
通過重定向 JavaScript 包含,研究人員可以執行惡意 JavaScript 來破壞 Netflix 帳戶,并竊取密碼和信用卡號。通過循環運行這種攻擊,研究人員可以在沒有用戶交互的情況下逐漸攻擊網站的所有活躍用戶,這種嚴重程度是請求走私的典型表現。
【點擊查看安全學習攻略】-私信回復資料獲取白帽黑客技術資料
針對Application Load Balancer(簡稱ALB)的HTTP Desync攻擊
接下來,讓研究人員看看一個簡單的 H2.TE HTTP Desync。 RFC 狀態為“任何包含特定于連接的標頭字段的消息都必須被視為格式錯誤。”
一個特定于連接的標頭字段是Transfer-Encoding。Amazon Web Services (AWS)的應用ALB未能遵守此行,并接受包含Transfer-Encoding的請求。這意味著攻擊者可以通過 H2.TE HTTP Desync來利用幾乎所有使用它的網站。
其中一個易受攻擊的網站是Verizon的執法入口網站,位于id.b2b.oath.com。研究人員使用以下請求利用了它:
前端將此請求進行了降級:
降級后,“transfer-encoding: chunked”標頭文件優先于前端插入的內容長度。這使得后端提前停止解析請求正文,并使研究人員能夠將任意用戶重定向到在psres.net的網站。
H2.TE通過請求標頭注入
由于HTTP/1是明文協議,所以不可能在某些地方放置某些解析關鍵字符。例如,你不能在標頭文件值中放入\r\n序列,這樣你就只會終止標頭文件。
在HTTP/2中壓縮標頭的方式,使你可以把任意字符放在任意位置。一個易受攻擊的實現是 Netlify CDN,它在基于它的每個網站上啟用了 H2.TE HTTP Desync攻擊,包括 Firefox 的 start.mozilla.org 起始頁面。研究人員制作了一個在標頭值中使用 ‘\r\n’ 的漏洞:
在降級過程中,\r\n觸發了一個請求標頭注入漏洞,引入了一個名為Transfer-Encoding: chunked額外標頭。
這觸發了 H2.TE HTTP Desync,其前綴旨在讓受害者從自己的 Netlify 域接收惡意內容。由于 Netlify 的緩存設置,有害響應將被保存并持續提供給任何其他試圖訪問相同 URL 的用戶。這樣攻擊者就可以完全控制 Netlify CDN 上每個網站的每個頁面。
H2.TE通過標頭名稱注入
Atlassian嘗試不允許在標頭值中使用換行符,但未能過濾標頭名稱。這很容易被攻擊者利用,因為服務器允許在標頭名稱中使用冒號,這在HTTP/1.1中是不可能實現的。
最初的修復程序也沒有過濾偽標頭,導致請求行注入漏洞。利用這些很簡單,只要可視化注入發生的位置,并確保得到的HTTP/1.1請求有一個有效的請求行:
修復程序的最后一個漏洞是一個典型的錯誤,即阻止’ r\n’,而不是阻止’ n’本身,后者幾乎總是被利用。
隱匿隧道攻擊
大多數前端很可以通過任何連接發送任何請求,從而實現跨用戶攻擊。然而,你會發現你的前綴只會影響來自你自己 IP 的請求。發生這種情況是因為前端為每個客戶端 IP 使用與后端的單獨連接。這有點麻煩,但你通常可以通過緩存攻擊間接攻擊其他用戶來解決該問題。
其他一些前端在來自客戶端的連接和到后端的連接之間強制執行一對一的關系。這是一個更嚴格的限制,但是常規的緩存攻擊和內部標頭泄漏技術仍然適用。
當前端選擇從不重用與后端的連接時,攻擊就會變得非常具有挑戰性。此時發送直接影響后續請求的請求是不可能的:
首先是確認漏洞,你可以通過發送一系列請求并查看早期請求是否影響后期請求來確認常規請求走私漏洞。不幸的是,這種技術總是無法確認請求隧道,因此很容易將漏洞誤認為是誤報。
研究人員需要一種新的確認技術,即簡單地走私一個完整的請求,然后看看你是否得到兩個響應:
假如你在HTTP/2響應正文中看到HTTP/1標頭,你就會發現自己是一個HTTP Desync:
前端服務器通常使用后端響應上的 Content-Length 來決定從套接字讀取多少字節。這意味著即使你可以向后端發出兩個請求,并從中觸發兩個響應,前端也只將第一個不太有趣的響應傳遞給你。
在以下示例中,由于突出顯示了 Content-Length,以橙色顯示的403響應從未傳遞給用戶:
終端返回的響應太大,導致Burp Repeater稍微滯后,所以研究人員決定將研究人員的方法從POST切換到HEAD來縮短它。這實際上是要求服務器返回響應標頭,但省略了響應正文:
果然,這導致后端只服務響應標頭,包括未傳播正文的Content-Length標頭!這使得前端過度讀取并提供對第二個走私請求的部分響應:
走私無效請求也會讓后端關閉連接,避免意外響應隊列攻擊的可能性。請注意,如果目標僅易受隧道攻擊,則響應隊列攻擊是不可能的,因此你無需擔心。有時,當 HEAD 失敗時,其他方法(如 OPTIONS、POST 或 GET)會起作用。研究人員已經將這種技術添加到HTTP Request Smuggler作為檢測方法。
請求隧道使你可以使用前端完全未處理的請求到達后端,最明顯的利用路徑是利用它繞過諸如路徑限制之類的前端安全規則。但是,你經常會發現沒有任何相關規則可以繞過。幸運的是,還有第二種選擇。
前端服務器通常會注入用于關鍵功能的內部標頭,例如指定用戶登錄的身份。由于前端檢測并重寫它們,直接利用這些標頭的嘗試通常會失敗。你可以使用請求隧道繞過此重寫并成功走私內部標頭。
不過有一個問題,攻擊者通常看不到內部標頭,并且很難利用不知名的標頭。只要服務器的內部標頭在Param Miner的wordlist中,并且在服務器的響應中引起可見的差異,Param Miner就應該檢測到它。
內部標頭泄漏
不存在于 Param Miner 的靜態詞表中或在網站流量中泄露的自定義內部標頭可能會逃避檢測。常規請求走私可用于使服務器將其內部標頭泄露給攻擊者,但這種方法不適用于請求隧道。如果你可以通過 HTTP/2 在標頭中注入換行符,那么還有另一種發現內部標頭的方法。經典的HTTP Desync攻擊依賴于讓兩個服務器對請求正文的結束位置產生分歧,但是使用換行符,研究人員可以讓服務器對正文的開始位置產生分歧!
為了獲得bitbucket使用的內部標頭,研究人員發出了以下請求:
在降級之后,它看起來是這樣的:
可以看到,前端認為’s=cow’是標頭文件的一部分,所以在此之后插入內部標頭。這意味著后端最終將內部標頭視為研究人員發送到 Wordpress 搜索功能的 ‘s’ POST 參數的一部分,并將它們反射回來:
在 bitbucket.org 上訪問不同的路徑會導致研究人員的請求被路由到不同的后端,并泄漏不同的標頭:
你也許可以使用隧道來進行更強大的各種 Web 緩存攻擊。此時你需要通過 H2.X desync 獲得請求隧道,HEAD 技術有效,并且存在緩存。這將允許你使用 HEAD 通過混合和匹配任意標頭和正文創建的有害響應來攻擊緩存。
經過一番挖掘,研究人員發現獲取 /wp-admin 會觸發一個重定向,該重定向反映了 Location 標頭內的用戶輸入,而不對其進行編碼。就其本身而言,這是完全無害的 - Location 標頭不需要 HTML 編碼。然而,通過將它與來自 /blog/404 的響應標頭配對,研究人員可以欺騙瀏覽器來呈現它,并執行任意的JavaScript:
HTTP / 2漏洞利用原語
接下來,讓研究人員看看一些HTTP/2利用原語,本節不提供完整的案例研究。
模糊性和 HTTP/2
在HTTP/1中,重復標頭對于各種攻擊都有用,但不可能發送具有多個方法或路徑的請求。HTTP/2決定用偽headers替換請求行,這意味著這現在是可能的。研究人員觀察到接受多個 :path 標頭的真實服務器,并且服務器實現在它們處理的 :path 中不一致:
此外,盡管 HTTP/2 引入了 :authority 標頭來替換 Host 標頭,但 Host 標頭在技術上仍然是允許的。事實上,據研究人員所知,兩者都是可選的。這為 Host-header 攻擊創造了充足的機會,例如:
URL前綴注入
HTTP/2的另一個不能忽略的特性是:scheme偽標頭,這個值意味著’http’或’https’,但它支持任意字節。
包括 Netlify 在內的一些系統使用它來構建 URL,而不執行任何驗證。這使你可以覆蓋路徑,并在某些情況下執行緩存攻擊:
其他人使用該方案構建請求路由到的 URL,從而創建 SSRF 漏洞。
與本文中使用的其他技術不同,即使目標沒有進行 HTTP/2 降級,這些漏洞也會起作用。
標頭名稱Split
你會發現有些服務器不允許你在標頭名稱中使用換行符,但允許使用冒號。由于在降級過程中末尾會附加冒號,這很少啟用完全HTTP Desync:
它更適合 Host-header 攻擊,因為 Host 應該包含一個冒號,并且服務器通常會忽略冒號之后的所有內容:
請求行(Request-Line) 注入
研究人員確實找到了一臺服務器,其中標頭名稱Split啟用了HTTP Desync。在測試中,漏洞消失了,服務器橫幅報告說他們已經更新了他們的 Apache 前端。為了追蹤這個漏洞,研究人員在本地安裝了舊版本的Apache。不過研究人員無法復制這個漏洞。
Apache 的 mod_proxy 允許在 :method 中使用空格,從而啟用請求行注入。如果后端服務器容忍請求行末尾的垃圾,這可以讓你繞過阻止規則:
逃避子文件夾:
標頭篡改
HTTP/1.1曾經有一個功能叫做行折疊,你可以在標頭值后面加上一個空格,隨后的數據就會被折疊起來。
下面是一個正常發送的相同請求:
使用行轉移:
該功能后來被棄用,但許多服務器仍然支持它。
如果你發現一個網站的 HTTP/2 前端允許你發送以空格開頭的標頭名稱,而后端支持換行,則你可以篡改其他標頭,包括內部標頭。這是研究人員篡改了內部標頭請求 ID 的示例,它是無害的,但在后端反映了有用的信息:
許多前端不會對傳入的標頭文件進行排序,所以你會發現通過移動空格標頭,你可以篡改不同的內部和外部標頭文件。
白帽黑客資料
安全建議
如果你正在設置 Web 應用程序,千萬不要讓 HTTP/2 降級,這是上述這些漏洞得逞的根本原因。
總結
以上是生活随笔為你收集整理的【网络安全】针对 HTTP/2 协议的HTTP Desync攻击的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何使用ADLab搭建活动目录实验环境来
- 下一篇: 【安全漏洞】利用CodeQL分析并挖掘L