解析针对 HTTP/2 协议的不同步攻击
HTTP/2 很容易被誤認為是一種傳輸層協議,HTTP/2 (原名HTTP/2.0)即超文本傳輸協議 2.0,是下一代HTTP協議。是由互聯網工程任務組(IETF)的Hypertext Transfer Protocol Bis (httpbis)工作小組進行開發。是自1999年http1.1發布后的首個更新。HTTP 2.0在2013年8月進行首次合作共事性測試。在開放互聯網上HTTP 2.0將只用于https://網址,而 http://網址將繼續使用HTTP/1,目的是在開放互聯網上增加使用加密技術,以提供強有力的保護去遏制主動攻擊。DANE RFC6698允許域名管理員不通過第三方CA自行發行證書。在本文中,我將介紹由實現漏洞和 RFC 漏洞引起的多種新的 HTTP/2獨有的威脅。
首先,我將展示這些漏洞是如何啟用HTTP/2排他的不同步攻擊的,案例研究的目標是一些知名網站,這些網站的服務器包括亞馬遜的應用程序負載均衡器、WAF、CDN和大型科技公司定制的堆棧。這些漏洞通過劫持客戶端、木馬化緩存、還有竊取憑據來發起攻擊。
之后,我將介紹新的技術和工具來破解不同步驅動的請求隧道,一種廣泛但被忽視的請求走私(request smuggling)變體,通常被誤認為是攻擊誤報。最后,我將分享HTTP/2引入的多個新的利用原語,揭示新的服務器層和應用層攻擊表面。HTTP請求走私在 2005 年第一次被提出, 是一項用于干擾 HTTP 請求的技術,網站會處理來自用戶的多個 HTTP 請求,使用 request smuggling 可以干擾其他用戶的請求。 請求 smuggling 漏洞在實踐場景中經常發生,允許攻擊者繞過控制,獲得未授權的數據,并且直接攻陷應用的其他用戶。
HTTP / 2攻擊
使用HTTP/2的第一步是學習協議基礎。
我通過從標頭開始編寫 HTTP/2 客戶端來開始這項研究,得出的結論是,對于本文中描述的攻擊,我們可以忽略許多低級特性的細節,如幀和流。
雖然HTTP/2很復雜,但它被設計用來傳輸與HTTP/1.1相同的信息,這是兩個協議中表示的等效請求。
HTTP / 1.1:
HTTP / 2:
假設你已經熟悉了HTTP/1,那么你只需要理解三個新概念。
偽造的標頭文件
偽造的標頭文件(pseudo header),通常有TCP偽首部和UDP偽首部。在UDP偽首部中,包含32位源IP地址,32位目的IP地址,8位協議,16位UDP長度。通過偽首部的校驗,UDP可以確定該數據報是不是發給本機的,通過首部協議字段,UDP可以確認有沒有誤傳。
在HTTP/1中,請求的第一行包含請求方法和路徑。HTTP/2用一系列偽造標頭文件替換請求行。這五個偽造標頭很容易識別,因為它們是用冒號在名字的開標頭表示的:
二進制協議
HTTP/1是一個基于文本的協議,因此使用字符串操作解析請求。例如,服務器需要查找冒號以知道標題名何時結束。這種方法中潛在的模糊性使得不同步攻擊成為可能。HTTP/2是一個像TCP一樣的二進制協議,所以解析是基于預定義的偏移量,不容易出現模糊性。本文使用人類可讀的抽象而不是實際的字節來表示HTTP/2請求。例如,在網絡上,偽造標頭名稱實際上被映射到單個字節,它們實際上并不包含冒號。
消息長度
在HTTP/1中,每個消息體的長度通過Content-Length或Transfer-Encoding標頭表示。
在HTTP/2中,這些標頭是冗余的,因為每個消息正文都由具有內置長度字段的數據幀組成。這意味著消息長度的模糊性很小,可能會讓你想知道如何使用HTTP/2進行不同步攻擊。這樣解決辦法就成了HTTP/2降級。
HTTP / 2 不同步攻擊
通過 HTTP/2 降級請求走私
HTTP/2降級是指前端服務器向客戶端發送HTTP/2,但在將請求轉發到后端服務器之前,將請求重寫為HTTP/1.1。這種協議轉換支持一系列攻擊,包括HTTP請求走私:
典型的請求走私漏洞主要是因為前端和后端對于是否從其內容長度 (CL) 或傳輸編碼 (TE) 標頭導出請求的長度存在分歧。根據發生這種不同步的方式,漏洞被歸類為 CL.TE 或 TE.CL。
使用HTTP/2的前端幾乎總是使用HTTP/2的內置消息長度。然而,接收降級請求的后端不能訪問此數據,必須使用CL或TE標頭。這導致了兩種主要類型的漏洞:H2.TE和H2.CL。
案例研究
現在我們已經掌握了足夠多的理論,可以開始探索一些真正的漏洞了。為了找到這些問題,我使用基于超時的H1不同步檢測策略的一個改編版本,在HTTP Request Smuggler中實現了自動檢測。自動檢測后,我用它來掃描我的帶有漏洞賞金計劃的網站管道。除非另有說明,否則所有引用的漏洞均已被修復。
接下來,我將假設你已經熟悉了HTTP請求走私,如果你對HTTP請求走私還不是很了解,可以點開此視頻觀看詳細介紹。
Netflix 上的 H2.CL 不同步
由于HTTP/2的數據幀長度字段,Content-Length標頭是不需要的。然而,HTTP/2 RFC聲明該標頭是允許的,只要它是正確的。對于第一個案例研究,我們將目標鎖定為www.netflix.com,它使用了一個無需驗證內容長度就執行HTTP降級的前端。這啟用了H2.CL不同步。
為了利用它,我發出了以下HTTP/2請求:
在前端將此請求降級為HTTP/1.1后,它到達后端,看起來像這樣:
由于 Content-Length 不正確,后端提前停止處理請求,橙色數據被視為另一個請求的開始。這使我能夠為下一個請求添加任意前綴,而不管它是誰發送的。
我精心設計了橙色前綴以觸發響應,將受害者的請求重定向到我的服務器 02.rs:
通過重定向 JavaScript 包含,我可以執行惡意 JavaScript 來破壞 Netflix 帳戶,并竊取密碼和信用卡號。通過循環運行這種攻擊,我可以在沒有用戶交互的情況下逐漸攻擊網站的所有活躍用戶,這種嚴重程度是請求走私的典型表現。
Netflix通過Zuul找到了這個漏洞,獲得了最高賞金2萬美元。現在這個漏洞已經被修復,并被定名為CVE-2021-21295。
應用程序負載均衡器上的 H2.TE 不同步
接下來,讓我們看看一個簡單的 H2.TE 不同步。 RFC 狀態為“任何包含特定于連接的標頭字段的消息都必須被視為格式錯誤。”
一個特定于連接的標頭字段是Transfer-Encoding。Amazon Web Services (AWS)的應用程序負載均衡器未能遵守此行,并接受包含Transfer-Encoding的請求。這意味著我可以通過 H2.TE 不同步來利用幾乎所有使用它的網站。負載均衡( LoadBalancer )可以通過彈性負載均衡從公網訪問到工作負載,與彈性IP方式相比提供了高可靠的保障,一般用于系統中需要暴露到公網的服務。而傳輸編碼在 HTTP 的報文標頭中,使用 Transfer-Encoding 首部進行標記,它就是指明當前使用的傳輸編碼。Transfer-Encoding 會改變報文的格式和傳輸的方式,使用它不但不會減少內容傳輸的大小,甚至還有可能會使傳輸變大,看似是一個不環保的做法,但是其實是為了解決一些特殊問題。
其中一個易受攻擊的網站是Verizon的執法入口網站,位于id.b2b.oath.com。我使用以下請求利用了它:
前端將此請求降級為:
這個看起來很熟悉,H2.TE的開發與CL.TE非常相似。降級后,“transfer-encoding: chunked”標頭文件優先于前端插入的內容長度。這使得后端提前停止解析請求正文,并使我們能夠將任意用戶重定向到我在psres.net的網站。
當我報告這個漏洞時,觸發器(trigger)要求我提供進一步的證據,證明我可能會造成傷害,所以我開始重定向實時用戶,很快發現我在OAuth登錄流程中捕捉到一些人,通通過 Referer 標頭泄露了他們的秘密代碼:
Verizon為此獎勵了7000美元的賞金。
我在accounts.athena.aol.com 上遇到了一個具有不同利用路徑的類似漏洞,支持各種新聞網站的 CMS,包括赫芬頓郵報和癮科技(Engadget)。利用該漏洞,我可以再次發出 HTTP/2 請求,該請求在降級后,命中后端并注入將受害者重定向到我的域的前綴:
另外觸發器(trigger)想要更多證據,所以我借此機會重定向了一些實時用戶。然而,這一次,重定向用戶導致向我的服務器發出請求,該請求實際上是“我可以向你發送我的憑證嗎?”:
我匆忙配置了我的服務器以授予他們權限:
并得到了一連串的贊揚:
這展示了我稍后需要探索的一些有趣的瀏覽器行為,并且還從 Verizon 那里獲得了另外 1萬美元。
我還直接向Amazon報告了這個root漏洞,Amazon現在已經修復了應用程序負載均衡器,這樣他們的客戶的網站就不會再被這個漏洞了影響了。每個使用Imperva的Cloud WAF的網站也很容易受到此攻擊,這時web應用防火墻的長期防護缺陷,使網站更容易被黑客攻擊。
H2.TE通過請求標頭注入
由于HTTP/1是明文協議,所以不可能在某些地方放置某些解析關鍵字符。例如,你不能在標頭文件值中放入\r\n序列,這樣你就只會終止標頭文件。
HTTP/2的二進制設計,結合它壓縮標頭的方式,使你可以把任意字符放在任意位置。服務器期望通過額外的驗證步驟重新施加HTTP/1格式的限制:
任何包含標頭字段值中不允許的字符的請求都必須被視為格式錯誤
當然,許多服務器都會跳過這個驗證步驟。
一個易受攻擊的實現是 Netlify CDN,它在基于它的每個網站上啟用了 H2.TE 不同步攻擊,包括 Firefox 的 start.mozilla.org 起始頁面。我制作了一個在標頭值中使用 ‘\r\n’ 的漏洞:
在降級過程中,\r\n觸發了一個請求標頭注入漏洞,引入了一個名為Transfer-Encoding: chunked額外標頭。
這觸發了 H2.TE 不同步,其前綴旨在讓受害者從我自己的 Netlify 域接收惡意內容。由于 Netlify 的緩存設置,有害響應將被保存并持續提供給任何其他試圖訪問相同 URL 的人。實際上,我可以完全控制 Netlify CDN 上每個網站的每個頁面。
H2.X 通過請求拆分
Atlassian 的 Jira 看起來也有類似的漏洞,我創建了一個簡單的概念驗證,旨在觸發兩個不同的響應,一個正常的響應和 robots.txt 文件。實際結果完全是另一回事,具體視頻請點此觀看。
服務器開始向我發送明顯針對其他Jira用戶的響應,包括大量敏感信息和PII。
這是因為我在制作有效載荷時做了一個小優化,我已經決定,與其使用\r\n來走私一個Transfer-Encoding標頭文件,不如使用double-\r\n來終止第一個請求,讓我直接在標頭文件中包含惡意前綴:
這種方法避免了對分塊編碼、消息正文和 POST 方法的需要。但是,它未能說明 HTTP 降級過程中的關鍵步驟,前端必須以 \r\n\r\n 序列終止標頭。這導致它終止前綴,將其變成一個完整的獨立請求:
后端看到的不是通常的1.5個請求,而是2個請求。我收到了第一個響應,但下一個用戶收到了對我走私請求的響應。然后,他們應該收到的響應被發送給下一個用戶,以此類推。實際上,前端開始無限期地為每個用戶提供對前一個用戶請求的響應。
更糟糕的是,其中一些包含了Set-Cookie標頭文件,它會持續地將用戶登錄到其他用戶的帳戶中。部署修復程序后,Atlassian 選擇全局過期所有用戶會話。
在使用 HTTP 請求走私的實際攻擊中提到了這種潛在影響,但我認為這種普遍性被低估了。出于顯而易見的原因,我沒有在許多網站上試驗過,但據我所知,這種利用路徑幾乎總是存在的。因此,如果你發現請求走私漏洞并且供應商在沒有更多證據的情況下不會認真對待它,那么走私兩個請求應該可以讓他們得到正在尋找的證據。
【邀你進網絡安全學習交流群】
總結
以上是生活随笔為你收集整理的解析针对 HTTP/2 协议的不同步攻击的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【安全漏洞】ThinkPHP 3.2.3
- 下一篇: 网络安全人才的发展情况是怎么样的呢?快上