百度空间 | 百度首页 
 
查看文章
 
HeapCommitRoutine 的技巧
2008-12-28 22:05

2005年的时候Nicolas Waisman就在他的《Owning the windows Heap》中提到了一个0day技巧,就是在堆溢出中覆盖HeapCommitRoutine的指针来获取程序的控制权限。

在Windows 2000中,我们还可以沿用覆盖PEB中lock/unlock的指针的方法,但是再XP SP2/2003中,PEB随机化,TOP SEH等关键指针都已经被encode了,所以只好找各个.dll的.data中的指针,但是这些指针地址往往和系统版本,语言版本,SP版本相关。

而HeapCommitRoutine指针存在于默认进程堆偏移0x57c处,而且默认进程堆的地址是比较固定的(Vista ALSR 除外)。

0:009> dt ntdll!_HEAP 0x150000
   +0x000 Entry            : _HEAP_ENTRY
   +0x008 Signature        : 0xeeffeeff
   +0x00c Flags            : 2
   +0x010 ForceFlags       : 0
   +0x014 VirtualMemoryThreshold : 0xfe00
   +0x018 SegmentReserve   : 0x100000
   +0x01c SegmentCommit    : 0x2000
   +0x020 DeCommitFreeBlockThreshold : 0x200
   +0x024 DeCommitTotalFreeThreshold : 0x2000
   +0x028 TotalFreeSize    : 0x1b5
   +0x02c MaximumAllocationSize : 0x7ffdefff
   +0x030 ProcessHeapsListIndex : 1
   +0x032 HeaderValidateLength : 0x608
   +0x034 HeaderValidateCopy : (null)
   +0x038 NextAvailableTagIndex : 0
   +0x03a MaximumTagIndex : 0
   +0x03c TagEntries       : (null)
   +0x040 UCRSegments      : (null)
   +0x044 UnusedUnCommittedRanges : 0x001505a8 _HEAP_UNCOMMMTTED_RANGE
   +0x048 AlignRound       : 0xf
   +0x04c AlignMask        : 0xfffffff8
   +0x050 VirtualAllocdBlocks : _LIST_ENTRY [ 0x150050 - 0x150050 ]
   +0x058 Segments         : [64] 0x00150640 _HEAP_SEGMENT
   +0x158 u                : __unnamed
   +0x168 u2               : __unnamed
   +0x16a AllocatorBackTraceIndex : 0
   +0x16c NonDedicatedListLength : 1
   +0x170 LargeBlocksIndex : (null)
   +0x174 PseudoTagEntries : (null)
   +0x178 FreeLists        : [128] _LIST_ENTRY [ 0x1da3c0 - 0x1da3c0 ]
   +0x578 LockVariable     : 0x00150608 _HEAP_LOCK
   +0x57c CommitRoutine    : (null)
   +0x580 FrontEndHeap     : 0x00150688
   +0x584 FrontHeapLockCount : 0
   +0x586 FrontEndHeapType : 0x1 ''
   +0x587 LastSegmentIndex : 0 ''

这个指针会在Heap extend的时候被调用,调用该指针的函数为RtlpFindAndCommitPages(),如下所示:

0:008> bl
0 e 7c833bf9     0001 (0001) 0:**** ntdll!RtlpFindAndCommitPages+0x51
0:008> g
Breakpoint 0 hit
eax=00150000 ebx=0201e5e0 ecx=0201e5e0 edx=00002000 esi=00150598 edi=00150640
eip=7c833bf9 esp=0201e5a0 ebp=0201e5b4 iopl=0         nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000             efl=00000246
ntdll!RtlpFindAndCommitPages+0x51:
7c833bf9 8b887c050000    mov     ecx,dword ptr [eax+57Ch] ds:0023:0015057c=00000000

0:009> r ecx=0x55705570       // 设置HeapCommitRoutine的指针为0x55705570 :)
0:009> r
eax=00150000 ebx=0201e5e0 ecx=55705570 edx=00002000 esi=00150598 edi=00150640
eip=7c833bff esp=0201e5a0 ebp=0201e5b4 iopl=0         nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000             efl=00000246
ntdll!RtlpFindAndCommitPages+0x57:
7c833bff 85c9            test    ecx,ecx

0:009> t
eax=00150000 ebx=0201e5e0 ecx=55705570 edx=00002000 esi=00150598 edi=00150640
eip=7c833c01 esp=0201e5a0 ebp=0201e5b4 iopl=0         nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000             efl=00000202
ntdll!RtlpFindAndCommitPages+0x59:
7c833c01 0f8597f00100    jne     ntdll!RtlpFindAndCommitPages+0x5b (7c852c9e) [br=1]     // 如果该指针不为NULL,跳转
0:009> t
eax=00150000 ebx=0201e5e0 ecx=55705570 edx=00002000 esi=00150598 edi=00150640
eip=7c852c9e esp=0201e5a0 ebp=0201e5b4 iopl=0         nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000             efl=00000202
ntdll!RtlpFindAndCommitPages+0x5b:
7c852c9e 53              push    ebx
0:009> u eip L 10
ntdll!RtlpFindAndCommitPages+0x5b:
7c852c9e 53              push    ebx
7c852c9f 8d5514        lea     edx,[ebp+14h]
7c852ca2 52              push    edx
7c852ca3 50              push    eax
7c852ca4 ffd1            call    ecx                              // 执行指针的地方

0:009> g
(a64.fb0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00150000 ebx=0201e5e0 ecx=55705570 edx=0201e5c8 esi=00150598 edi=00150640
eip=55705570 esp=0201e590 ebp=0201e5b4 iopl=0         nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000             efl=00010202
55705570 ??     

Vista下这个指针也被encode了,但是还是可以利用的,有兴趣的可以参考Ben Hawkes的《Attacking The Vista Heap》,或者下次有空的时候讲Vista下覆盖Heap handle的时候再讨论。


类别:网络安全 | 添加到搜藏 | 分享到i贴吧 | 浏览() | 评论 (11)
 
最近读者:
 
网友评论:
1
2008-12-28 22:56 | 回复
好在 都是 微软的系统 还是有共同点的 收藏起来 到 被窝里 慢慢看 学习中
 
2
2008-12-29 01:26 | 回复
居然找不到《Owning the windows Heap》,请问能不能给各链接?
 
3
2008-12-29 09:49 | 回复
牛B啊,又多学了一招
 
4
2008-12-29 11:14 | 回复
DM 能不能共享一下《Owning the windows Heap》这篇文章? 目前还灭有搜索到。
 
5
2008-12-29 17:10 | 回复
那篇文章很老了还是讲的2000上的堆,除了这个信息,其他东西没啥价值。
 
6
2008-12-29 21:09 | 回复
DM,当年ms08-046的利用应该也可以用这个吧,覆盖函数指针,然后在Heap extend的时候造成该指针的调用。这样,堆cookie和safe unlink也不起作用了。
 
7
2008-12-29 22:12 | 回复
还是共享一下吧,谢谢
 
8
2008-12-29 22:35 | 回复
楼上的在IRC 上pm我邮件地址吧。
 
9
2008-12-30 00:30 | 回复
麻烦dm也传一份给我 kernel213@126.com
 
10
2008-12-30 14:35 | 回复
7楼的 ~ 不是我~ 草~
 
11
2008-12-30 18:56 | 回复
MS08_046的确可以覆盖这个指针来获得利用。
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu