BlackHat论文解读: HTTP 标头,请求走私,缓存中毒

概念:

 

1.现代web架构:基于反向代理转发的二层结构,如下图1所示。

2.http标头,请求走私:在http-header中修改制定参数参数名或值,以实现在front 到 back中调用链中的攻击,造成缓存攻击,ip限制,速率绕过等。如下图2所示。

3. 缓存中毒:利用front的缓存,覆盖原始访问的内容,如下图3所示,我们可以任意更改rsp-body里的值。

影响:

1. 绕过网关 IP 限制和速率限制(仅仅修改转发参数即可攻击漏洞):

API Gateway 允许你使用以下资源策略来限制 API 访问某些 IP 地址:

此策略将访问限制为仅接受来自 IP 地址 1.2.3.4和私有范围 10.0.0.0/8 的请求。来自其他 IP 地址的请求遇到漏洞:

请求

响应

不出所料,简单地向请求添加“X-Forwarded-For”标头与 AWS 的安全控制不匹配:

要求

然而,当应用一个允许标头信息走私到这个标头信息的突变时,就会授予访问权限:

请求

响应

这允许绕过 IP 限制,但在实际情况下可能很难实现。来自私有范围的地址是显而易见的猜测,但如果这些不被允许,那么就很难猜测一个已被授予访问权限的IP地址。

请求

响应

事实证明,在请求中添加标头“x - forward - for abcd: z”可以在API网关中绕过AWS资源策略的IP限制。

AWS Cognito速率限制

在渗透测试期间,我在 AWS Cognito 中发现了一个类似但非常小的漏洞。Cognito 是一个身份验证提供程序,你可以将其集成到你的应用程序中以帮助处理身份验证。

在短时间内向“ConfirmForgotPassword”或“ForgotPassword”目标发出五次请求后,我的IP地址被暂时封锁。但是,在请求中添加“X-Forwarded-For:[0x0b]z”允许再发出 5 个请求。不幸的是,不可能在此标头中循环不同的值或有效的 IP 地址继续获得五次尝试,这意味着此漏洞的影响很小。然而,它仍然是一个很好的例子,说明如何使用头部走私来绕过速率限制。

2. 缓存攻击

在我向AWS报告后,他们立即修复了IP限制绕过。当重新测试时,我注意到我仍然可以使用相同的变体将标头走私到后端服务器,这让我想知道是否还有其他有趣的标头值得尝试。

API 网关可能在内部使用了一些很有趣的标头,但我无法识别其中的任何一个。真正引人注目的是”Host”标头,如果我试图将这个标头偷偷传递到后端服务器会发生什么。

我使用 API Gateway 设置了两个 API:一个“受害者”API 和一个“攻击者”API:

请求

响应

请求

响应

当在常规“Host”标头旁边包含一个变异的“Host”标头时,就会出现有趣的行为:

请求

响应

API 网关正在从变异的“Host”标头中指定的 API 返回响应。这与大多数 Web 服务器的行为形成对比,后者不会将变异的“Host”标头视为“Host”标头,而是从常规“Host”标头中获取主机。当这样的服务器充当 API 网关前的缓存时,这会变得很有趣,因为它会缓存上述请求的结果,就好像它是对“victim.i.long.lat”的请求一样,即使响应是来自“attacker.i.long.lat”API。

为了演示这一点,我使用“AllViewer”请求策略在 API 网关前面设置了 CloudFront,这会导致所有标头都被转发。发送上述请求,然后请求“https://victim.i.long.lat/a”,显示攻击者API的响应已经存储在受害者API的缓存中:

请求

响应

请求

响应

这种缓存攻击很容易被利用,因为攻击者可以设置自己的API并返回任意路径的任意内容。这允许他们完全覆盖受害者缓存中的任何条目,有效地允许他们完全控制受害者API的内容。

3. 请求走私

在 Black Hat USA 2020 上,Amit Klein 提出了一个基于 2 个“Content-Length”标头的请求走私(“CL.CL”请求走私)。当使用在同一连接中发送的以下请求将 Squid 用作 Abyss Web 服务器前的反向代理时,可能会触发该漏洞:

第一个请求以绿色显示,包含两个“Content-Length”标头,一个是变异的,另一个是未变异的。Squid 只会解析未变异的标头文件,并将第一个请求的主体长度取为 33 字节,以蓝色显示。Squid 然后将第二个请求作为红色显示的请求——对“/doesntexist”的“GET”请求。

另一方面,Abyss 将解析变异和未变异的“Content-Length”标头,并从变异标头中获取 0 字节的值。因此,它认为第二个请求是以蓝色开头的请求——对“/a.html”的“GET”请求。

这样做的总结果是,Abyss 以“/a.html”的内容响应,而 Squid 将此响应缓存到路径“/doesntexist”,从而导致缓存攻击。

Klein 的研究特别有趣,因为它表明 CL.CL 请求走私存在于现代系统中,他提出了一种使用超时安全检测请求走私的简单方法,该方法基于“内容长度”和“传输编码”标头(“CL.TE”和“TE.CL”请求走私)。此方法试图使后端期待比前端转发更多的内容,从而触发后端超时。通过首先扫描 CL.TE 请求走私,可以在测试易受攻击的系统时将影响其他用户请求的风险降至最低。

对 CL.CL 请求走私执行相同操作的尝试可能类似于以下情况:

对于前端读取未变异的“Content-Length”标头而后端读取变异版本的易受攻击的系统,这通常会导致超时。尽管在 Squid 和 Abyss 设置的情况下,不会导致超时,因为 Abyss 不会在回复“POST”请求之前等待正文发送。

当这个请求被发送到一个易受攻击的系统时,危险就来了,其中前端读取变异的标头,后端读取未变异的版本。前端服务器将转发“z”正文,后端服务器将其视为下一个请求的开始。然后套接字就被攻击了,并且由于后端服务器将请求方法视为例如“zGET”,因此另一个用户的请求失败的可能性很高。

如果我们不知道前端服务器将解析哪个“Content-Length”标头,我们既有可能会在易受攻击的系统中导致超时,也有可能发生套接字攻击,可能导致另一个用户的请求失败。

可以稍微修改用于检测标头走私的方法,以创建安全的 CL.CL 请求走私检测方法。以下示例展示了如何使用这种修改后的方法来检测 Squid 和 Abyss 中的 Klein 漏洞。

首先,使用正在测试的“Content-Length”标头对向目标系统发送 "baseline" 请求:

请求

响应

下一步是再发送两次相同的请求,在每个“Content-Length”标头中都有一个垃圾值:

请求

响应

请求

响应

比较 3 个响应,我们注意到:

包含垃圾值的请求都触发了与"baseline"响应不同的响应,这表明至少有 1 个服务器正在解析每个标头的值。

对包含垃圾值的请求的响应是不同的。这表明漏洞来自不同的服务器,因此链中的不同服务器正在解析不同版本的“Content-Length”标头。

这些情况表明潜在的 CL.CL 请求走私,当调查超出这一点时,重要的是要知道前端服务器正在解析哪个标头,以最大限度地减少使套接字攻击和影响其他用户的机会。

这可以通过发送带有单个未变异的“Content-Length”标头的请求并观察产生的漏洞来实现:

请求

响应

由于前端服务器几乎肯定会解析此请求中的“Content-Length”标头,因此产生的漏洞很可能是由前端服务器生成的。通过将此漏洞与该过程中早期生成的漏洞进行比较,我们看到它与在同一请求中发送标头“Content-Length: z”和“Content-Length abcd: 0”时生成的漏洞相同。因此,前端服务器解析未变异的“Content-Length”标头,后端服务器解析变异的1。

这些请求仅表明存在潜在的请求走私漏洞,尽管还远未确定。例如,许多服务器会处理两种形式的“Content-Length”标头,但是当它们具有不同的值时就会出现漏洞,从而无法进行请求走私。

参考:

https://i.blackhat.com/EU-21/Wednesday/EU-21-Thatcher-Practical-HTTP-Header-Smuggling.pdf

实用的 HTTP 标头走私:通过反向代理攻击 AWS

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值