在过去的十来年中,前端开发已经发生了巨大的变化。大多数现代Web应用程序都是使用AngularJS,React,Vue等框架构构建的。谷歌表示:"AngularJS是一个基于JavaScript的开源前端Web框架,主要由Google、个人以及企业社区维护,以解决开发单页应用程序时遇到的许多问题。"大多数人认为这些框架能够抵抗XSS之类的漏洞,但是事实并非如此,仅仅是利用的方式有所不同而已。
在上手Angular应用程序之前,你需要了解一些前驱知识。我这里简要介绍一些,比如模板,表达式以及作用域,这些对于理解Angular中的客户端模板注入至关重要。
当你在浏览器中查看Angular应用程序时,实际上是在查看模板。模板也就是一段HTML代码段,它告诉Angular如何在angular应用中渲染组件。模板的主要优点是,它可以传递数据,从而允许你基于传递给它的参数动态生成html代码。下面是一段示例代码:
可以看到,该模板创建了一个h1的标签,该标签的内容为欢迎当前的用户。{{Username}}
是一个表达式,可以根据实际的用户名进行更改。如果用户名为"ghostlulz",则该应用将显示"Welcome ghostlulz!"。这样Angular就可以动态生成HTML页面,而不是使用静态页面:
表达式就像Javascript代码段一样。和JS表达式类似,Angular表达式可以包含文本、运算符以及变量,比方说:
与JS表达式不同的是,Angular表达式通过Scope对象来操作全局窗口。比方说你想要执行“alert(1)”的时候,它并不会执行,因为scope对象并没有alert函数,除非你自己定义一个。scope是一个你可以自定义变量和函数的对象,如下所示:
根据谷歌的描述:
当使用客户端模板框架的应用程序将用户输入动态嵌入到网页中时,就会出现客户端模板注入漏洞。
如你所知,Angular是一个客户端模板框架,你可以将用户输入嵌入这些模板中。这使得Angular成为这类漏洞的理想目标。
在本文的示例中,将会使用liveoverflow提供的在线环境进行演示:
https://old.liveoverflow.com/angularjs/
如果你对Angular应用中测试XSS不是很了解的话,你可能进行如下的操作:
可以看到,这样并不能实现弹框。因为服务器在将我们输入的内容在传给模板之前进行了一次编码,操作如下:
这是一种很常见防止XSS的方法,并且被众多的应用所采纳,但是Angular有些不同。在Angular中,我们可以使用不带特殊字符的表达式,这些特殊字符通过php的"
htmlspecialchars"函数处理之后,可以得到如下结果:
正如你所看到的,我这里使用表达式"{{1+1}}"得到了执行的结果"2". 这就是一个很明显的信号,说明这个应用可能存在客户端模板注入。
让应用程序实现两个数字相加并不能让我们得到满足,我们是不是可以注入Javascript代码呢?通过前面的介绍,我们无法简单的插入"alert(1)"来执行,因为我们输入的"alert(1)",在后台会变成"$scope.alert(1)"的形识执行,由于$scope中没有相关的函数定义,所以没法执行。
默认情况下,scope对象包含另一个"
constructor(构造)"对象,这个对象中包含一个函数为"constructor(构造)"函数。这个函数可以动态的生成、执行代码。实际上我们只需要如下操作,便可以执行我们的XSS payload:
值得注意的是这端注入的代码中没有包含特殊字符,也就是说,任何通过编码的方式来阻止XSS的方式都会失败,而大部分的人正是通过这种方式来阻止XSS.
如你所见,我们构造的Angular表达式被注入到页面中,导致页面动态生成并执行代码。
为了防止此类攻击,Angular1.2 – 1.5引入沙箱机制,不过后来在1.6版本中又移除了,因为沙箱并没有真正提高安全等级,存在绕过的可能。如果你测试的时候使用的是1.2到1.5之间的版本,可以查一下对应版本的绕过沙箱的方式。
新技术可能会引入新的安全问题。我们要认识到任何接受用户输入的客户端模板框架都容易受到客户端模板注入的攻击。本文中的漏洞主要用于触发XSS有效负载。由于angular使用表达式,因此我们经常可以绕过传统的XSS预防措施,比方说对用户输入进行编码。大多数开发人员严重依赖于这种防止方法,这种防止方法在大多数应用程序中都可以正常工作,但是在使用客户端模板和表达式的应用可能就没有效果了。
原文连接:http://ghostlulz.com/angularjs-client-side-template-injection-xss/
翻译:看雪翻译组-skeep
校对:看雪翻译组-sudozhange
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2020-4-19 21:29
被skeep编辑
,原因: 修改原文链接