[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吧!


<<:  Day-19 Excel列印时常见问题

>>:  Day04 安装Django

那些被忽略但很好用的 Web API / Battery

低电量~低~低~电量~ 吕士轩-低电量 今天要分享的也是一个使用情境偏少的 API,但如果你有想要...

Day18 订单 -- 优惠项目

前几天我们把购物车流程跑完了,其中有讲到优惠的部份, 因此我们订单需要新增table来储存该内容,这...

Day27 - 在 Kubernetes Ingress 挂上 Google SSL 凭证

取得 SSL 凭证的方式 在 Day26 我们建立了 Ingress,使服务能透过 Domain N...

从零开始的8-bit迷宫探险【Level 21】进击的主角!暴风雨来呐,你坐啊!

远方有个一闪一闪的东西,吸引了山姆的目光。 「这颗水晶...特别的大颗!」山姆跑了过去。 碰触到魔...

Day15-Vue SFC 单一元件档

SFC是什麽 Single-file components单一元件档是一个集合HTML、JavaSc...