导语:HTTP/2 (原名HTTP/2.0)即超文本传输协议 2.0,是下一代HTTP协议。是由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis (httpbis)工作小组进行开发。
HTTP/2 很容易被误认为是一种传输层协议,HTTP/2 (原名HTTP/2.0)即超文本传输协议 2.0,是下一代HTTP协议。是由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis (httpbis)工作小组进行开发。是自1999年http1.1发布后的首个更新。HTTP 2.0在2013年8月进行首次合作共事性测试。在开放互联网上HTTP 2.0将只用于https://网址,而 http://网址将继续使用HTTP/1,目的是在开放互联网上增加使用加密技术,以提供强有力的保护去遏制主动攻击。DANE RFC6698允许域名管理员不通过第三方CA自行发行证书。在本文中,我将介绍由实现漏洞和 RFC 漏洞引起的多种新的 HTTP/2独有的威胁。
首先,我将展示这些漏洞是如何启用HTTP/2排他的不同步攻击的,案例研究的目标是一些知名网站,这些网站的服务器包括亚马逊的应用程序负载均衡器、WAF、CDN和大型科技公司定制的堆栈。这些漏洞通过劫持客户端、木马化缓存、还有窃取凭据来发起攻击。
之后,我将介绍新的技术和工具来破解不同步驱动的请求隧道,一种广泛但被忽视的请求走私(request smuggling)变体,通常被误认为是攻击误报。最后,我将分享HTTP/2引入的多个新的利用原语,揭示新的服务器层和应用层攻击表面。HTTP请求走私在 2005 年第一次被提出, 是一项用于干扰 HTTP 请求的技术,网站会处理来自用户的多个 HTTP 请求,使用 request smuggling 可以干扰其他用户的请求。 请求 smuggling 漏洞在实践场景中经常发生,允许攻击者绕过控制,获得未授权的数据,并且直接攻陷应用的其他用户。
HTTP / 2攻击
使用HTTP/2的第一步是学习协议基础。
我通过从标头开始编写 HTTP/2 客户端来开始这项研究,得出的结论是,对于本文中描述的攻击,我们可以忽略许多低级特性的细节,如帧和流。
虽然HTTP/2很复杂,但它被设计用来传输与HTTP/1.1相同的信息,这是两个协议中表示的等效请求。
HTTP / 1.1:
HTTP / 2:
假设你已经熟悉了HTTP/1,那么你只需要理解三个新概念。
伪造的标头文件
伪造的标头文件(pseudo header),通常有TCP伪首部和UDP伪首部。在UDP伪首部中,包含32位源IP地址,32位目的IP地址,8位协议,16位UDP长度。通过伪首部的校验,UDP可以确定该数据报是不是发给本机的,通过首部协议字段,UDP可以确认有没有误传。
在HTTP/1中,请求的第一行包含请求方法和路径。HTTP/2用一系列伪造标头文件替换请求行。这五个伪造标头很容易识别,因为它们是用冒号在名字的开标头表示的:
二进制协议
HTTP/1是一个基于文本的协议,因此使用字符串操作解析请求。例如,服务器需要查找冒号以知道标题名何时结束。这种方法中潜在的模糊性使得不同步攻击成为可能。HTTP/2是一个像TCP一样的二进制协议,所以解析是基于预定义的偏移量,不容易出现模糊性。本文使用人类可读的抽象而不是实际的字节来表示HTTP/2请求。例如,在网络上,伪造标头名称实际上被映射到单个字节,它们实际上并不包含冒号。
消息长度
在HTTP/1中,每个消息体的长度通过Content-Length或Transfer-Encoding标头表示。
在HTTP/2中,这些标头是冗余的,因为每个消息正文都由具有内置长度字段的数据帧组成。这意味着消息长度的模糊性很小,可能会让你想知道如何使用HTTP/2进行不同步攻击。这样解决办法就成了HTTP/2降级。
HTTP / 2 不同步攻击
通过 HTTP/2 降级请求走私
HTTP/2降级是指前端服务器向客户端发送HTTP/2,但在将请求转发到后端服务器之前,将请求重写为HTTP/1.1。这种协议转换支持一系列攻击,包括HTTP请求走私:
典型的请求走私漏洞主要是因为前端和后端对于是否从其内容长度 (CL) 或传输编码 (TE) 标头导出请求的长度存在分歧。根据发生这种不同步的方式,漏洞被归类为 CL.TE 或 TE.CL。
使用HTTP/2的前端几乎总是使用HTTP/2的内置消息长度。然而,接收降级请求的后端不能访问此数据,必须使用CL或TE标头。这导致了两种主要类型的漏洞:H2.TE和H2.CL。
案例研究
现在我们已经掌握了足够多的理论,可以开始探索一些真正的漏洞了。为了找到这些问题,我使用基于超时的H1不同步检测策略的一个改编版本,在HTTP Request Smuggler中实现了自动检测。自动检测后,我用它来扫描我的带有漏洞赏金计划的网站管道。除非另有说明,否则所有引用的漏洞均已被修复。
接下来,我将假设你已经熟悉了HTTP请求走私,如果你对HTTP请求走私还不是很了解,可以点开此视频观看详细介绍。
Netflix 上的 H2.CL 不同步
由于HTTP/2的数据帧长度字段,Content-Length标头是不需要的。然而,HTTP/2 RFC声明该标头是允许的,只要它是正确的。对于第一个案例研究,我们将目标锁定为www.netflix.com,它使用了一个无需验证内容长度就执行HTTP降级的前端。这启用了H2.CL不同步。
为了利用它,我发出了以下HTTP/2请求:
在前端将此请求降级为HTTP/1.1后,它到达后端,看起来像这样:
由于 Content-Length 不正确,后端提前停止处理请求,橙色数据被视为另一个请求的开始。这使我能够为下一个请求添加任意前缀,而不管它是谁发送的。
我精心设计了橙色前缀以触发响应,将受害者的请求重定向到我的服务器 02.rs:
通过重定向 JavaScript 包含,我可以执行恶意 JavaScript 来破坏 Netflix 帐户,并窃取密码和信用卡号。通过循环运行这种攻击,我可以在没有用户交互的情况下逐渐攻击网站的所有活跃用户,这种严重程度是请求走私的典型表现。
Netflix通过Zuul找到了这个漏洞,获得了最高赏金2万美元。现在这个漏洞已经被修复,并被定名为CVE-2021-21295。
应用程序负载均衡器上的 H2.TE 不同步
接下来,让我们看看一个简单的 H2.TE 不同步。 RFC 状态为“任何包含特定于连接的标头字段的消息都必须被视为格式错误。”
一个特定于连接的标头字段是Transfer-Encoding。Amazon Web Services (AWS)的应用程序负载均衡器未能遵守此行,并接受包含Transfer-Encoding的请求。这意味着我可以通过 H2.TE 不同步来利用几乎所有使用它的网站。负载均衡( LoadBalancer )可以通过弹性负载均衡从公网访问到工作负载,与弹性IP方式相比提供了高可靠的保障,一般用于系统中需要暴露到公网的服务。而传输编码在 HTTP 的报文标头中,使用 Transfer-Encoding 首部进行标记,它就是指明当前使用的传输编码。Transfer-Encoding 会改变报文的格式和传输的方式,使用它不但不会减少内容传输的大小,甚至还有可能会使传输变大,看似是一个不环保的做法,但是其实是为了解决一些特殊问题。
其中一个易受攻击的网站是Verizon的执法入口网站,位于id.b2b.oath.com。我使用以下请求利用了它:
前端将此请求降级为:
这个看起来很熟悉,H2.TE的开发与CL.TE非常相似。降级后,“transfer-encoding: chunked”标头文件优先于前端插入的内容长度。这使得后端提前停止解析请求正文,并使我们能够将任意用户重定向到我在psres.net的网站。
当我报告这个漏洞时,触发器(trigger)要求我提供进一步的证据,证明我可能会造成伤害,所以我开始重定向实时用户,很快发现我在OAuth登录流程中捕捉到一些人,通通过 Referer 标头泄露了他们的秘密代码:
Verizon为此奖励了7000美元的赏金。
我在accounts.athena.aol.com 上遇到了一个具有不同利用路径的类似漏洞,支持各种新闻网站的 CMS,包括赫芬顿邮报和瘾科技(Engadget)。利用该漏洞,我可以再次发出 HTTP/2 请求,该请求在降级后,命中后端并注入将受害者重定向到我的域的前缀:
另外触发器(trigger)想要更多证据,所以我借此机会重定向了一些实时用户。然而,这一次,重定向用户导致向我的服务器发出请求,该请求实际上是“我可以向你发送我的凭证吗?”:
我匆忙配置了我的服务器以授予他们权限:
并得到了一连串的赞扬:
这展示了我稍后需要探索的一些有趣的浏览器行为,并且还从 Verizon 那里获得了另外 1万美元。
我还直接向Amazon报告了这个root漏洞,Amazon现在已经修复了应用程序负载均衡器,这样他们的客户的网站就不会再被这个漏洞了影响了。每个使用Imperva的Cloud WAF的网站也很容易受到此攻击,这时web应用防火墙的长期防护缺陷,使网站更容易被黑客攻击。
H2.TE通过请求标头注入
由于HTTP/1是明文协议,所以不可能在某些地方放置某些解析关键字符。例如,你不能在标头文件值中放入\r\n序列,这样你就只会终止标头文件。
HTTP/2的二进制设计,结合它压缩标头的方式,使你可以把任意字符放在任意位置。服务器期望通过额外的验证步骤重新施加HTTP/1格式的限制:
任何包含标头字段值中不允许的字符的请求都必须被视为格式错误
当然,许多服务器都会跳过这个验证步骤。
一个易受攻击的实现是 Netlify CDN,它在基于它的每个网站上启用了 H2.TE 不同步攻击,包括 Firefox 的 start.mozilla.org 起始页面。我制作了一个在标头值中使用 '\r\n' 的漏洞:
在降级过程中,\r\n触发了一个请求标头注入漏洞,引入了一个名为Transfer-Encoding: chunked额外标头。
这触发了 H2.TE 不同步,其前缀旨在让受害者从我自己的 Netlify 域接收恶意内容。由于 Netlify 的缓存设置,有害响应将被保存并持续提供给任何其他试图访问相同 URL 的人。实际上,我可以完全控制 Netlify CDN 上每个网站的每个页面。
H2.X 通过请求拆分
Atlassian 的 Jira 看起来也有类似的漏洞,我创建了一个简单的概念验证,旨在触发两个不同的响应,一个正常的响应和 robots.txt 文件。实际结果完全是另一回事,具体视频请点此观看。
服务器开始向我发送明显针对其他Jira用户的响应,包括大量敏感信息和PII。
这是因为我在制作有效载荷时做了一个小优化,我已经决定,与其使用\r\n来走私一个Transfer-Encoding标头文件,不如使用double-\r\n来终止第一个请求,让我直接在标头文件中包含恶意前缀:
这种方法避免了对分块编码、消息正文和 POST 方法的需要。但是,它未能说明 HTTP 降级过程中的关键步骤,前端必须以 \r\n\r\n 序列终止标头。这导致它终止前缀,将其变成一个完整的独立请求:
后端看到的不是通常的1.5个请求,而是2个请求。我收到了第一个响应,但下一个用户收到了对我走私请求的响应。然后,他们应该收到的响应被发送给下一个用户,以此类推。实际上,前端开始无限期地为每个用户提供对前一个用户请求的响应。
更糟糕的是,其中一些包含了Set-Cookie标头文件,它会持续地将用户登录到其他用户的帐户中。部署修复程序后,Atlassian 选择全局过期所有用户会话。
@defparam 在使用 HTTP 请求走私的实际攻击中提到了这种潜在影响,但我认为这种普遍性被低估了。出于显而易见的原因,我没有在许多网站上试验过,但据我所知,这种利用路径几乎总是存在的。因此,如果你发现请求走私漏洞并且供应商在没有更多证据的情况下不会认真对待它,那么走私两个请求应该可以让他们得到正在寻找的证据。
使 Jira 易受攻击的前端是 PulseSecure Virtual Traffic Manager。 为此,Atlassian 获得了 15000 美元赏金。
除了 Netlify 和 PulseSecure Virtual Traffic Manager 之外,该技术还适用于其他一些服务器。我们与计算机应急响应小组 (CERT) 合作,发现 F5 的 Big-IP 负载均衡器也容易受到攻击,要了解更多细节,请参阅咨询K97045220,它也适用于Imperva Cloud WAF。
本文翻译自:https://portswigger.net/research/http2如若转载,请注明原文地址