概念:
1.现代web架构:基于反向代理转发的二层结构,如下图1所示。
![](https://img-blog.csdnimg.cn/img_convert/220e23163deb3ff9cabfee2091e61eb0.png)
2.http标头,请求走私:在http-header中修改制定参数参数名或值,以实现在front 到 back中调用链中的攻击,造成缓存攻击,ip限制,速率绕过等。如下图2所示。
![](https://img-blog.csdnimg.cn/img_convert/7fe4d041785cdb66586ffad7876842de.png)
3. 缓存中毒:利用front的缓存,覆盖原始访问的内容,如下图3所示,我们可以任意更改rsp-body里的值。
![](https://img-blog.csdnimg.cn/img_convert/d8fa646908805c3d3dd87b5e6990a202.png)
影响:
1. 绕过网关 IP 限制和速率限制(仅仅修改转发参数即可攻击漏洞):
API Gateway 允许你使用以下资源策略来限制 API 访问某些 IP 地址:
![](https://img-blog.csdnimg.cn/img_convert/abf92783b7532483857628f150e4c059.png)
此策略将访问限制为仅接受来自 IP 地址 1.2.3.4和私有范围 10.0.0.0/8 的请求。来自其他 IP 地址的请求遇到漏洞:
请求
![](https://img-blog.csdnimg.cn/img_convert/20fcd88a98d8344cf7f1aef4981d77e5.png)
响应
![](https://img-blog.csdnimg.cn/img_convert/ce23527ca2219b2cdbcd4492f955e6f6.png)
不出所料,简单地向请求添加“X-Forwarded-For”标头与 AWS 的安全控制不匹配:
要求
![](https://img-blog.csdnimg.cn/img_convert/14f0540ddc3d09489995029ec6cf316d.png)
![](https://img-blog.csdnimg.cn/img_convert/6b3e6e95091db652f4fcd2fe982b6c07.png)
然而,当应用一个允许标头信息走私到这个标头信息的突变时,就会授予访问权限:
请求
![](https://img-blog.csdnimg.cn/img_convert/fcb680c03bfeedaef37bb649a4cac560.png)
响应
![](https://img-blog.csdnimg.cn/img_convert/dbfa1d75cd40fe30979319d1d429216e.png)
这允许绕过 IP 限制,但在实际情况下可能很难实现。来自私有范围的地址是显而易见的猜测,但如果这些不被允许,那么就很难猜测一个已被授予访问权限的IP地址。
请求
![](https://img-blog.csdnimg.cn/img_convert/0d6f57883aceba9b027c24fbc8a52d1e.png)
响应
![](https://img-blog.csdnimg.cn/img_convert/aa0e9a29598119716bae72569c18b2e4.png)
事实证明,在请求中添加标头“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:
请求
![](https://img-blog.csdnimg.cn/img_convert/73d1ad17184342c99b13fe6d6dfd1b95.png)
响应
![](https://img-blog.csdnimg.cn/img_convert/248324801f0a7514174236815961f612.png)
请求
![](https://img-blog.csdnimg.cn/img_convert/adb22e9b4272d800209b45ae650c111f.png)
响应
![](https://img-blog.csdnimg.cn/img_convert/eb3e7122708d4225376456c848eeb41a.png)
当在常规“Host”标头旁边包含一个变异的“Host”标头时,就会出现有趣的行为:
请求
![](https://img-blog.csdnimg.cn/img_convert/8dd5d71b23931372889347509448891c.png)
响应
![](https://img-blog.csdnimg.cn/img_convert/ceae210e06c26cb6e1a84dfa7a0e6f94.png)
API 网关正在从变异的“Host”标头中指定的 API 返回响应。这与大多数 Web 服务器的行为形成对比,后者不会将变异的“Host”标头视为“Host”标头,而是从常规“Host”标头中获取主机。当这样的服务器充当 API 网关前的缓存时,这会变得很有趣,因为它会缓存上述请求的结果,就好像它是对“victim.i.long.lat”的请求一样,即使响应是来自“attacker.i.long.lat”API。
![](https://img-blog.csdnimg.cn/img_convert/4624e34dde3cf1d81ac6bdd9e2c22bcd.png)
为了演示这一点,我使用“AllViewer”请求策略在 API 网关前面设置了 CloudFront,这会导致所有标头都被转发。发送上述请求,然后请求“https://victim.i.long.lat/a”,显示攻击者API的响应已经存储在受害者API的缓存中:
请求
![](https://img-blog.csdnimg.cn/img_convert/a4189396b8ce6cd92d93fef31ace65df.png)
响应
![](https://img-blog.csdnimg.cn/img_convert/96902e94cbfff35ec995ca6e9204468c.png)
请求
![](https://img-blog.csdnimg.cn/img_convert/302b3988abb8d67229b59f374a35d1c7.png)
响应
![](https://img-blog.csdnimg.cn/img_convert/967edd7f17c0c8b75d86fddec2590168.png)
这种缓存攻击很容易被利用,因为攻击者可以设置自己的API并返回任意路径的任意内容。这允许他们完全覆盖受害者缓存中的任何条目,有效地允许他们完全控制受害者API的内容。
3. 请求走私
在 Black Hat USA 2020 上,Amit Klein 提出了一个基于 2 个“Content-Length”标头的请求走私(“CL.CL”请求走私)。当使用在同一连接中发送的以下请求将 Squid 用作 Abyss Web 服务器前的反向代理时,可能会触发该漏洞:
![](https://img-blog.csdnimg.cn/img_convert/db02cb24778a1d607fbd594b44f9bc3e.png)
第一个请求以绿色显示,包含两个“Content-Length”标头,一个是变异的,另一个是未变异的。Squid 只会解析未变异的标头文件,并将第一个请求的主体长度取为 33 字节,以蓝色显示。Squid 然后将第二个请求作为红色显示的请求——对“/doesntexist”的“GET”请求。
另一方面,Abyss 将解析变异和未变异的“Content-Length”标头,并从变异标头中获取 0 字节的值。因此,它认为第二个请求是以蓝色开头的请求——对“/a.html”的“GET”请求。
![](https://img-blog.csdnimg.cn/img_convert/ba1c6eb8a94590018c3aeb37aa562166.png)
这样做的总结果是,Abyss 以“/a.html”的内容响应,而 Squid 将此响应缓存到路径“/doesntexist”,从而导致缓存攻击。
Klein 的研究特别有趣,因为它表明 CL.CL 请求走私存在于现代系统中,他提出了一种使用超时安全检测请求走私的简单方法,该方法基于“内容长度”和“传输编码”标头(“CL.TE”和“TE.CL”请求走私)。此方法试图使后端期待比前端转发更多的内容,从而触发后端超时。通过首先扫描 CL.TE 请求走私,可以在测试易受攻击的系统时将影响其他用户请求的风险降至最低。
对 CL.CL 请求走私执行相同操作的尝试可能类似于以下情况:
![](https://img-blog.csdnimg.cn/img_convert/1ec346e7c15c7945fe3e0e8a7f2dbc77.png)
对于前端读取未变异的“Content-Length”标头而后端读取变异版本的易受攻击的系统,这通常会导致超时。尽管在 Squid 和 Abyss 设置的情况下,不会导致超时,因为 Abyss 不会在回复“POST”请求之前等待正文发送。
当这个请求被发送到一个易受攻击的系统时,危险就来了,其中前端读取变异的标头,后端读取未变异的版本。前端服务器将转发“z”正文,后端服务器将其视为下一个请求的开始。然后套接字就被攻击了,并且由于后端服务器将请求方法视为例如“zGET”,因此另一个用户的请求失败的可能性很高。
如果我们不知道前端服务器将解析哪个“Content-Length”标头,我们既有可能会在易受攻击的系统中导致超时,也有可能发生套接字攻击,可能导致另一个用户的请求失败。
可以稍微修改用于检测标头走私的方法,以创建安全的 CL.CL 请求走私检测方法。以下示例展示了如何使用这种修改后的方法来检测 Squid 和 Abyss 中的 Klein 漏洞。
首先,使用正在测试的“Content-Length”标头对向目标系统发送 "baseline" 请求:
请求
![](https://img-blog.csdnimg.cn/img_convert/fd39d79ce6cb6ddda26e967cc6808585.png)
响应
![](https://img-blog.csdnimg.cn/img_convert/c1ce159d3f6b3377c2d887844a62dd49.png)
下一步是再发送两次相同的请求,在每个“Content-Length”标头中都有一个垃圾值:
请求
![](https://img-blog.csdnimg.cn/img_convert/c8e265e8a8ae0ee0442217ef3f711e34.png)
响应
![](https://img-blog.csdnimg.cn/img_convert/113ea9ef73384cb034fabaa749563446.png)
请求
![](https://img-blog.csdnimg.cn/img_convert/c59d0db5a7ce00a68be5830869d7de72.png)
响应
![](https://img-blog.csdnimg.cn/img_convert/4fa3d610578e0e90275ca150ab04ac2d.png)
比较 3 个响应,我们注意到:
包含垃圾值的请求都触发了与"baseline"响应不同的响应,这表明至少有 1 个服务器正在解析每个标头的值。
对包含垃圾值的请求的响应是不同的。这表明漏洞来自不同的服务器,因此链中的不同服务器正在解析不同版本的“Content-Length”标头。
这些情况表明潜在的 CL.CL 请求走私,当调查超出这一点时,重要的是要知道前端服务器正在解析哪个标头,以最大限度地减少使套接字攻击和影响其他用户的机会。
这可以通过发送带有单个未变异的“Content-Length”标头的请求并观察产生的漏洞来实现:
请求
![](https://img-blog.csdnimg.cn/img_convert/500c53dee9bc45e457d76e4e7678722d.png)
响应
![](https://img-blog.csdnimg.cn/img_convert/069934f29360bc1e669341c32fae0bd2.png)
由于前端服务器几乎肯定会解析此请求中的“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