繼續我們的:Requests Smuggling Attack[1] 主題!
其實,昨天介紹到的攻擊都只能針對 HTTP/1.1 進行,因為在 HTTP/2 架構下統一是由 Byte Framing 方式做資料處理和邊界定義,不再是經由 Header 去定義它們,而是 Key-Value 對應,這點跟前幾天介紹過的 HPACK 是高度相關的。
不過畢竟資料是後端 Server 在處理,今天如果只有前端 Server 限制只接受 HTTP/2 封包資料而 Server 依然信任 1.1,那攻擊者就可以進行所謂的 HTTP/2 Downgrade Attack!
當後端 Server 優先信任 Content Length:
(換個精準表達方法!這是 HTTP/2 中的壓縮 Header / HPACK 表達)
:method = POST
:path = /
:authority = vuln.whale-tw.com
content-length = 0
SMUGGLED
跟昨天一樣,導致請求被完全送向後端,但後端會因為讀取了 0 bytes 而自動把前端傳回的剩下地 SMUGGLED bytes 拼接到下一個使用者的請求中。
當後端 Server 優先信任 Transfer-Encoding:
又是一個依樣畫葫蘆地 Payload
:method = POST
:path = /
:authority = vuln.whale-tw.com
transfer-encoding = chunked
0
SMUGGLED
一樣,錯誤的 chunking 導致錯誤內容拼接。
想像很美好?不過不對,根據 RFC 7540 / 9113 [2] 規範,HTTP/2 是完全禁止(MUST NOT)出現 transfer-encoding: chunked
所以這只發生在前端較驗寬鬆,或者...
這就比較有趣了,由於 HTTP/2 是 Key-Value 對照結構,所以在它的 Byte Framing 視角中你恣意插入的 \r\n (CRLF: Carriage Return, Line Feed)不會影響解析結果
然而,當它送向後端 Server 時,如果後端 Server 僅支援 HTTP/1.1 協議,那它會把整個封包內容打開變成我們熟悉的樣態:
前端 Server HTTP/2 Byte Framing 結構視角:
:method = POST
:path = /
:authority = vuln.whale-tw.com
foo = bar\r\nTransfer-Encoding: chunked
後端 Server HTTP/1.1 傳統 HTTP 封包結構:
將換行符號(CRLF)一併展開合併進去封包
POST / 1.1
Foo: Bar
Transfer-Encoding: chunked
透過一次注入,成功讓前端沒看到被注入的 Header,卻又在後端發生生效!