iT邦幫忙

2021 iThome 鐵人賽

DAY 4
0
Security

讓Web開發者森77的Hacking Trick系列 第 4

[Day4] HTTP Request Smuggling - HTTP 請求走私

前言

上一篇玩完HTTP Method後,接著來玩Request的Data Length吧!

正文

概念

HTTP Request Smuggling是一種很獨特的攻擊方式,歷史上可以追溯到 2005 年。 這種攻擊會在普通 HTTP Request中偽造了一個額外的 HTTP Request——這是由於前端Server和後端Server之間對於HTTP Request長度解釋不同造成的,這點可以從字面上看出一二,用簡略的方式說就是一種以合法掩飾非法的攻擊方法。
下圖是一個簡單版的HTTP Request Smuggling示意圖


歷史講古

在 2005 年的研究中,Watchfire首次這種攻擊手法,而且提出了三種 HTTP Request smuggling的Attack vectors:

  • Web Cache Poison
  • Bypass Firewall
  • Stealing other users' credentials

從上面這些就可以看出HTTP Request Smuggling可以很容易的跟其他的攻擊方法結合,例如Stealing other users' credentials,若是網站中原本就具有反射式XSS漏洞(RXSS),就可以透過Smuggling的方式,特製一個Request讓後端Server認為是"下一個"使用者發送的Request,將這個RXSS的Response彈給其他用戶,迫使正常使用者瀏覽到惡意內容,導致cookie被竊取。可以參考下圖:
一般的RXSS:

透過HTTP Request Smuggling觸發RXSS影響其他用戶:

或是利用301 Moved Permanently將下個使用者route到自己所架設的web service,在下面的Case Study會講到。

接著2015年的DEF CON24上,一篇Hiding Wookiees in HTTP,展示了眾多的HTTP Request Smuggling技術、變種,例如NULL Character Injection、Huge Header、NoCache Poisoning和Chunk size attribute truncation(屬性截斷)...等。

2019年的Blackhat上,開發Burp Suite的portswigger提出了基於Transfer-Encoding變種的HTTP Request Smuggling,並成功拿下爆破了Trello的Bug Bounty。HTTP Desync Attacks: Request Smuggling Reborn

接著是2020年Blackhat,SafeBreach Labs的HTTP Request Smuggling In 2020再次提出了五個變種,像是:Header SP/CR junk就使用了基於Content-Length的變種(如Content-Length Kuku: 3)造成web server在解釋長度時誤判。這個研究也成功bypass了mod_security CRS防禦。

一般認為,解決HTTP Request Smuggling的方法是:

  1. 禁止re-use TCP Connection
  2. 前端和後端使用完全一樣的Web Server或確保Web Server的對於內容長度解釋的方式完全一致
  3. 使用HTTP/2
    然而,使用HTTP/2就沒事了嗎,HTTP/2: The Sequel is Always Worse通過這種被稱為h2c smuggling的方法,bypass了reverse proxy的訪問控制。h2c會從客戶端發起HTTP/1.1 upgrade request,等收到101 Switching Protocols的response後,客戶端會reuse connection再根據新約定的protocol傳輸數據。

其他還有像是web socket 走私透過Reverse Proxy發送upgrade request,但Sec-WebSocket-Version header使用錯誤的protocol版本,porxy沒有驗證這個header認為upgrade request是正確的,最後將request轉發到後端。


類型

一般最基礎的類型大概有4種,當然,透過上面的講古之後,就知道這些不是全部,也並非絕對需要CL(Content-Length)或TE(Transfer-Encoding)才能達成。

  • CL-TE
POST / HTTP/1.1
Host: example.com
Content-Length: 6
Transfer-Encoding: chunked

0

X

基本概念是前端優先判斷CL作為data長度邊界,而後端優先判斷TE。
CL的value為6,這個值會覆蓋到第8行的X,但後端因為優先判斷TE的關係,遇到第6行的0(這是代表TE的中止),因此將第7行之後的內容判斷為下一個Request的開始,使下一個request的Method變成XGET/XPOST之類的。

  • TE-CL
POST / HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-length: 3
Transfer-Encoding: chunked

3
X

0

與上個情況大致相同,不一樣的是,前端優先判斷TE,後端則是CL,所以將長度交換過來就好。

  • TE-TE
POST / HTTP/1.1
Host: example.com
Content-Length: 3
Transfer-Encoding: chunked
Transfer-Encoding: cow

3
X

0

這邊比較特別的是使用了一個正確value的TE、一個錯誤value的TE和一個CL。如果”前端”Server因此判斷TE為錯誤的header而去parse CL,那麼就變成了CL-TE攻擊。反之,如果”後端”Server判斷 TE為錯誤的header的話,就會成為 TE-CL 攻擊。

  • CL-CL
GET / HTTP/1.1
Host: example.com
Content-Length: 3
Content-Length: 0

X

也稱為double Content-Length attack,這比較容易理解。這是大多數Web Server和Middware對GET Method Request中Request body的鬆散判斷,導致漏洞的發生,因為一般來說GET Method的request body是不會有data的。


Case Study

這是一個來自Hackerone的案例:
Mass account takeovers using HTTP Request Smuggling on https://slackb.com/ to steal session cookies

(圖源同上)

研究員在 https://slackb.com/ 上發現了一個 CL-TE 類型的 HTTP Request smuggling來竊取session cookie 的大規模帳戶接管。受害者request被Hijacked並迫使受害者透過網站的Open redirect, route到到自己所架設的web service。

  1. 使用CL-TE在slackb.com上做Poison Socket劫持受害者的Request,將slackb.com上的Request改為使用GET <url> HTTP/1.1
    (紅色部分中的是研究員用Burp架設的web service,綠色部分則是受害者發出的request)
  2. 將正常使用者的Request Line透過寫入X:X將它轉變成無效的Start Line 使原本用戶的request line被改寫
  3. 後端Server收到GET <url> HTTP/1.1後,引起301重新導向到研究者架設的web service並攜帶slack cookie達到帳戶接管的效果。

下篇預告 :HTTP Header Injection,來玩玩Header吧!


上一篇
[Day3] HTTP Verb/Method Tampering - HTTP 動詞竄改
下一篇
[Day5] HTTP Header Injection - HTTP Header 注入
系列文
讓Web開發者森77的Hacking Trick30

尚未有邦友留言

立即登入留言