使用XSSI攻击获取敏感信息

admin 2021年5月6日04:09:53评论135 views字数 4065阅读13分33秒阅读模式

前言

CSP(内容安全策略)是防御XSS的绝佳方法,不同于以往过滤关键字的手段,它要求将内嵌脚本独立到外部文件中,并通过白名单的方式指定了哪些外部资源是可加载的。CSP在协议层面杜绝了XSS攻击,一度被誉为XSS终结者。但有趣的是,当敏感脚本被独立到文件中时,就很容易造成另一种漏洞——XSSI(跨站脚本包含)。当无法对XSS进行利用时,我们不妨对这类漏洞进行深入探究。

XSSI的原理

XSSI与XSS、CSRF同为针对客户端攻击的漏洞,它们的不同点在于,XSS是在受害者页面中放置恶意代码,CSRF是跨域在受害者页面执行一个恶意动作,而XSSI旨在跨域包含含有敏感数据的脚本以获取敏感数据。

众所周知,同源策略(SOP)是浏览器最核心最基本的安全策略,同源是指协议、域名、端口相同,非同源的资源不能互相读写。而script标签是允许跨域加载资源的,如果某个网站的动态脚本、文件或响应中包含某些敏感信息(比如唯一标识符、个人资料、防御CSRF的Token),便有信息泄露的风险。传统的XSSI攻击场景如下:恶意页面B使用script标签包含了目标网站A用来储存敏感数据的信息源C(可能是动态脚本、文件或响应),当攻击者引导受害者访问B时,由于受害者此时在A处于登录态,B可以轻松获取C中包含的受害者的敏感信息。

耳熟能详的JSON和JSONP劫持其实是XSSI最为容易利用的一种漏洞场景,本文对此不做深入讲解。在更多的场景中,我们想要获取的敏感信息无法直接被Javascript读取,需要精心构造Payload以窃取它们,甚至强行将其内容变为可读的Javascript变量,这也是下文将重点讨论的部分。

获取JS脚本中的敏感信息

根据XSSI的定义,静态JS文件也可能泄露敏感信息,比如一个Secret_key:
<!--恶意页面-->
<script type="text/javascript" src="http://127.0.0.1:8802/leaked/js1.js">
//注意这里是被恶意包含的文件
</script>
<script type="text/javascript">
$('#leaked_content').text(Secret_key);
</script>

恶意页面地址为127.0.0.1:80/index.html,端口号不同已经跨域。

使用XSSI攻击获取敏感信息
不过显然这样的XSSI意义不大,因为直接读取JS文件也可获得。XSSI多针对动态JS文件进行攻击,因为这样的脚本通常在用户处于登录态时容易包含敏感信息。比如这样的形式:
//储存敏感信息的js
var session = getSession();

在敏感数据存在于全局变量中时,这种窃取极为容易进行。当然,敏感数据更多的是存在于局部变量中。

//储存敏感信息的js
(function(){
var session = getSession();
doSomeThing(session);
})();

很多网站会将一些基本的功能函数写入一个JS文件,以便在写业务逻辑时方便重用,如上图的doSomeThing函数,我们可以通过重写此函数的方式获取敏感数据。
<!--恶意页面-->
<script type="text/javascript">
window.data = '';
function doSomeThing(d){
window.data = d
}
</script>
<script type="text/javascript" src="http://127.0.0.1:8802/leaked/js1.js">
//注意这里是被恶意包含的文件
</script>
<script type="text/javascript">
$('#leaked_content').text(window.data);
</script>

如图,传入doSomeThing函数的内容已经被泄露:

使用XSSI攻击获取敏感信息
如果没有自定义函数可以进行重写,我们可以通过重写原型链来获取数据。如果读者对JS没有研究,可以暂且粗劣的理解为内置函数。比如下面的情况:
//储存敏感信息的js
(function(){
function setInfo() {
var session = getSession();
var sid = session.split(/;|=/)[1];
//...
//do some thing...
}
//...
setInfo();
//...
})();

由于session是String类型的,在split时会调用String原型链中的split方法,此时我们只需重写此方法即可。
<!--恶意页面-->
<script type="text/javascript">
window.data = '';
String.prototype.split = function(param) {
window.data = this.toString();
return [null, this];
}
</script>
<script type="text/javascript" src="http://127.0.0.1:8802/leaked/js1.js">
//注意这里是被恶意包含的文件
</script>
<script type="text/javascript">
$('#leaked_content').text(window.data);
</script>
</html>

如下图,我们已经成功的获取了Session值。

使用XSSI攻击获取敏感信息
针对不同的情况,我们可以使用不同的方法来获取敏感数据,以上仅列举了其中几种情况。那么应该如果快速分辨一个JS文件是否为动态JS文件?当有Cookie和无Cookie时请求所响应的文件内容不同时,即可确定这是一个动态JS文件了,当然并不是每一个动态JS文件都可以被利用。我们可以使用Burpsuite的插件DetectDynamicJS来完成这项工作,此插件已在github上开源。

链接地址:
https://github.com/portswigger/detect-dynamic-js

获取其他文件或响应中的敏感信息

响应中的敏感信息主要涉及到JSON劫持,这里仅提一个tip:对于一些开源框架的get注入,若注入点存在于需要身份验证才能访问的页面(比如后台),可以通过读取注入后返回的JSON从而拿到敏感数据。

下面将详细探讨如何获取文件中的敏感信息。文件内容并不能直接作为一个Javascript变量的值读取,以及文件是有多行的,这使得获取文件内容十分困难。

有研究员在Paper中提出使用script标签的charset属性将包含的文件编码为UTF-16,其目的在于强制文件的所有内容连为一体,变为一个未定义的Javascript变量。然后通过在window域内使用onerror捕获错误信息(此错误信息一定为已编码的文件内容 is not defined),再进行解码即可。此举其实是为了防止符号会引起Javascript出现其他异常,例如英文逗号会截断文件内容,报错只会显示逗号前的内容未定义;而中文逗号则会直接提示非法字符,从而获取不到任何敏感信息。这其实和在利用PHP伪协议读取文件源代码时先base64编码有异曲同工之妙。然而此种方法如今在主流浏览器上已经无法成功了。

此处我们使用另一种方法来获取敏感信息:倘若敏感文件中有我们能够操控的字段,我们就可以利用JS的语法来构造函数或多行字符串变量以窃取可控字段之间的内容。

假设有两个字段是可控的:
//源文件
此处是可控变量1
搜索到t1ddl3r的身份证号码为1234567890,电话为987654321。
以上为t1ddl3r的所有信息。
此处是可控变量2

我们可以使用ECMAScript 6引入的箭头函数来包含它们:
//源文件
//经过我们注入两个变量构造后的文件
此处是=i=>/*
搜索到t1ddl3r的身份证号码为1234567890,电话为987654321。
以上为t1ddl3r的所有信息。
此处是*/i

可以看到我们已经定义了一个叫做此处是的函数,可以使用toString方法查看它的内容:

使用XSSI攻击获取敏感信息
假设可控字段只有一处,为下方t1ddl3r处:
搜索到t1ddl3r的身份证号码为1234567890,电话为987654321。
以上为t1ddl3r的所有信息
此时我们可以利用反引号来构建多行字符串,将t1ddl3r替换为=`,t1ddl3r:

搜索到=,t1ddl3r的身份证号码为1234567890,电话为987654321。
以上为=
,t1ddl3r的所有信息
如图,我们已经定义了一个名为搜索到的多行字符串变量:

使用XSSI攻击获取敏感信息
当然此种利用方式较为苛刻,不仅要有可控变量,还要保证我们存值的变量前没有任何异常语法干扰,这是因为Javascript一旦遇到异常就会停止往后解析。比如下面这种情况:
s_name,s_number=`
test,1234567890
s_name,s_number=`

由于我们存入多行字符串的可控变量s_number前的s_name被解析为一个未定义变量,会引发错误而停止向下解析:

使用XSSI攻击获取敏感信息

结语

永远不要将敏感数据存在某些文件中,响应敏感JSON的API也应该仅接受POST请求。或许XSSI不是那种可以获取服务器权限的漏洞,但其所造成的敏感信息泄露的安全问题是不可忽视的。

参考文献

  1. Identifier based XSSI attacks
  2. CROSS-SITE SCRIPT INCLUSION, A FAMELESS BUT WIDESPREAD WEB VULNERABILITY CLASS
  3. Your Scripts in My Page:What Could Possibly Go Wrong?

相关推荐: 攻防演练之蓝队视角下的Linux信息收集

前言上一篇 红队视角下Linux信息收集 我们谈到红队是以提权和后渗透为主要目的而进行的信息收集,本次谈一谈在蓝队应急响应中Linux系统下比较关键的内容。日志Linux系统的日志功能非常强大且完善,几乎可以保存所有的操作记录,蓝队的信息收…

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年5月6日04:09:53
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   使用XSSI攻击获取敏感信息https://cn-sec.com/archives/246197.html