UAF漏洞分析之CVE-2012-4969

by Netfairy - 2015-12-14

前言

20129月,通用漏洞与披露平台发布了一个存在IE浏览器的UAF漏洞。

原文:Use-after-free vulnerability in the CMshtmlEd::Exec function in mshtml.dll in Microsoft Internet Explorer 6 through 9 allows remote attackers to execute arbitrary code via a crafted web site, as exploited in the wild in September 2012

报告指出:Microsoft Internet Explorer 69版本中的’mshtml.dll’中的‘CMshtmlEd::Exec’函数中存在释放后使用漏洞。远程攻击者可利用该漏洞通过特制的网站,执行任意代码。

环境

操作系统:Windows 7 sp1

浏览器:IE 8.0.7601.17514

漏洞文件:mshtml 8.0.7601.17514

调试器:windbg

漏洞验证

这个漏洞我在网上没有搜到POC,但是Metasploit有,于是在WIN下装了个MetasploitSearch CVE-2012-4969 搜索相关exploit

image1.png

Use exploit/windows/browser/ie_execcommand_uaf选中这个模块

image2.png

set payload windows/exec 选择payload,也就是shellcode

image3.png

Shop options看看需要设置的参数

image4.png

这里我们只需设置好以上两个参数即可。然后就exploit

image5.png

此时在虚拟机访问这个网址,就能执行shellcode。但是我在测试的时候IE只是崩溃了,没弹出计算器

image6.png

没有攻击成功,真是忧伤。值得庆幸的是漏洞触发了。下面我们开始分析这个漏洞。但是,每次都要访问http://192.168.56.1:8080/b6xa9i7Tb去触发漏洞显然不行。主要是漏洞分析经常需要修改POC,另外就是开个MSF有点卡。PS:说了那么多,还不是因为没钱更新硬件。然后我就想把http://192.168.56.1:8080/b6xa9i7Tb网页提取到本地,之前直接在IE缓存目录下提取的网页不能触发崩溃,经流离大神提醒,用Charles抓包一对比,发现抓包得到的和缓存的有些不一样。用抓包到的网页一试

image7.png

成功把POC提取到本地,Metasploit可以Shutdown了,话说Metasploit真是好东西。Exploit贼多。


漏洞分析

前面一个我提取到两个html文件,命名为poc.htmlpoc_1.html。由于poc.html太长,故不能完整截图,如需要这两个文件,可联系我netfairy@qq.com

image8.pngWindbg调试前先设置hpaust标志。附加IE后,打开poc.html

image9.png

看看崩溃点前后信息,可以看到

6bd1503e 8b7f08          mov     edi,dword ptr [edi+8] ds:0023:0bb74f80=????????
6bd15041 8b07            mov     eax,dword ptr [edi]
6bd15043 57              push     edi
6bd15044 ff5008           call      dword ptr [eax+8]

猜测[edi+8]edi是对象一的地址,这个对象偏移8处又保存对象二的地址。接下来取对象二的虚表指针,然后调用虚表偏移8处的虚函数。值得我们关注的是对象一,显然,这里edi是一个无效地址,猜想应该是对象一释放后又被重新访问导致,【注:下面所说的对象均指对象一】往前看:

image10.png

Edi又来源于CMshtmlEd::Exec函数的第一个参数,所以edi指向CMshtmlEd对象实例。那么,问题来了:

->这个对象在哪创建
->哪里释放它
->哪里又重新使用它

第三个问题解决了,重用点就是:

6bd1503e 8b7f08          mov     edi,dword ptr [edi+8] ds:0023:0bb74f80=????????
6bd15041 8b07            mov     eax,dword ptr [edi]
6bd15043 57              push    edi
6bd15044 ff5008           call    dword ptr [eax+8]
为了找出分配和释放点,我通常是查看CMshtmlEd类的成员函数,在IDA中搜索CMshtmlEd

image11.png

凭男人的第六感,圈出来的两个像是对象创建和释放函数。由于前面设置了ust,顺便追踪下对象的分配,但不知为何之前可以后来没有显示

image12.png

之前是有看到释放发生在CMshtmlEd::Release的。关掉windbg,重新附加IE,执行

x mshtml!CMshtmlEd:*
image13.png

在上图这三个函数下断,记录执行过程如下:

->mshtml!CMshtmlEd::Release: 0cc14f78
->mshtml!CMshtmlEd::Initialize: 0cc22fc0
->mshtml!CMshtmlEd::Initialize: 0cd3efc0
->mshtml!CMshtmlEd::Release:
->mshtml!CMshtmlEd::Exec:
->mshtml!CMshtmlEd::Release:
->mshtml!CMshtmlEd::Release: 08dfef78
->mov     edi,dword ptr [edi+8] ds:0023:08dfef80=???????? //edi=08dfef78

看到了释放和重用,确没有看到对象创建。先不管,看到没:mshtml!CMshtmlEd::Exec这个函数很可疑,在它下面就是对象释放和重用,所以我们单独对mshtml!CMshtmlEd::ExecCMshtmlEd::Release下断跟踪

image14.png

首次在mshtml!CMshtmlEd::Exec断下来后,单步跟踪。跟踪到

6a4a5037 e820000000      call    mshtml!CCommand::Exec (6a4a505c)

这个call调用CMshtmlEd::Release。记录被对象的地址是:0x080b4f78。

接着函数返回,继续往下执行,然后就

image15.png

看到了吧,前脚释放CMshtmlEd对象,后脚就引用它,所以导致了异常。现在,我们想要知道哪句代码触发了这个UAF漏洞,回头看看POC:poc.htmlpoc_1.html。我发现poc_1.html

image16.png

这两行代码比较可疑:首先有经验可知write常常会触发对象释放,再看后像是一个对象占位动作。为了证实猜测:我加两个断点如下:

image17.png

同时在CMshtmlEd::Release也下断,重新调试

image18.png

确定后断在

image19.png

跟到对象释放点

image20.png

看这个对象地址,此时这个对象还没有被释放【注:由于重启地址会变,所以下图的0x08b74f78就是前面的0x0c62bf78

image21.png

继续运行,第二个框弹出

image22.png

Windbg Break一下,再去0x0c62bf78看看

image23.png

非法地址,说明对象在

document.write("d");

这条指令被释放。然后我们继续运行

image24.png

0x0c62bf78还是非法地址,说明

parent.arrr[0].src = "YMjf\u0c08\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH";

并未占位成功。继续运行

image25.png

直接到了崩溃点。由此可以知道对象在哪释放,在哪占位。同时也知道POC没有执行成功是由于

parent.arrr[0].src = "YMjf\u0c08\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH";

占位失败。搞清楚了这些关系之后,就可以开始构造我们自己的EXP了。


EXP构造

构造EXP需要处理两个关键的地方:

->堆喷射
->对象占位

我们先来解决对象占位的问题我把源代码稍微修改了一点:

function funcA() {
      document.write("d");
      for(var i = 0; i<0x150; i++)
      {
        parent.arrr[0].src = "YMjf\u0c0c\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH";
      }

调试结果如下图

image26.png
我们成功占位,所以可以控制原对象的数据。这里是0x0c0c0c0c。再看
6c42503e 8b7f08          mov     edi,dword ptr [edi+8] 
6c425041 8b07            mov     eax,dword ptr [edi]  
6c425043 57              push    edi
6c425044 ff5008           call    dword ptr [eax+8]

只需在0x0c0c0c0c往后填充大量的0x0c0c0c0c+shellcoe,程序最终就会从0x0c0c0c0c开始执行,一直执行到我们的shellcode。这可以通过spray实现,这个技术很老了,但是现在应用还是非常的普遍。继续看poc.html

image27.png

已经存在喷射代码,但似乎在win7喷射失败。那么我们需要改写它以适应win7。我修改了poc1.html如下图:

image28.png

Poc.html如下图:
image29.png
我也是我将目标改为0x0f0c0c0c而不是0x0c0c0c0c。结果:

image30.png
能执行到\x90,即nop。但是好像产生了一个异常,并且在我多次测试后发现只有少数次能喷射到0x0f0c0c0c。也就是说如果拿这个EXP去用,可能100次只有10次是成功的。不过任凭我怎么改都无法稳定喷射到0x0f0c0c0c0x0c0c0c0c或者别的地址。好吧!留下这个问题,我们一起来探讨如何?