Type: 00020000 MEM_PRIVATE
Allocation Base: 22520000
Allocation Protect: 00000001 PAGE_NOACCESS
可以发现,edi所代表的内存也位于一个页堆上,其属性为不可访问。查看页堆的详细信息:
0:034> !heap -p -a 0x225ff000
address 225ff000 found in _DPH_HEAP_ROOT @ 6ff1000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
1794116c: 225feff8 4 - 225fe000 2000
74c08e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77451d4e ntdll!RtlDebugAllocateHeap+0x00000030
7740b586 ntdll!RtlpAllocateHeap+0x000000c4
773b3541 ntdll!RtlAllocateHeap+0x0000023a
74b10269 MSVCR100!malloc+0x0000004b
61bbb327 mfc100u+0x000bb327
67b83043 AviSplitter+0x00003043
67b8333f AviSplitter+0x0000333f
页堆的起始地址为0x225feff8,大小是4个字节。而edi为0x225ff000,位于起始地址8字节之后:
0x225ff000-0x225feff8 = 8
查看该页堆的内容:
0:034> dd 0x225feff8
225feff8 31786469 00000002 ???????? ????????
225ff008 ???????? ???????? ???????? ????????
通过前面分析已经知道,漏洞现场向edi位置拷贝的al是poc.avi样本中倒数第二个字节,对比样本内容:
00000260h: 64 62 00 00 00 00 69 64 78 31 02 00 00 00 00 00
可以发现,页堆的前8个字节已经被拷贝为样本最后两个字节之前的8字节内容。
查看memcpy函数的参数:
0:034> kv
ChildEBP RetAddr Args to Child
1613f2d0 67b87339 225ff000 231f726e 00000002 MSVCR100!memcpy+0x196
根据memcpy函数原型:
void *memcpy(void *dest, const void *src, size_t n);
可知:
目的地址: 225ff000
源地址: 231f726e
拷贝大小: 00000002
可以发现,memcpy函数从样本内容的0x26e位置开始拷贝,拷贝大小为2字节。
不难总结出以下现象:
a. 进程准备向大小只有4 bytes的页堆拷贝poc.avi样本中最后两个字节时,造成了溢出
b. 页堆在漏洞现场的memcpy函数使用前,已经被写入了8个字节的内容,其中第5-8字节写入的内容,也属于溢出部分
c. 这8个字节的内容与文件中倒数第二个字节之前的8个字节内容相同
当然,分析到这里,已经得知, edi来自于系统malloc函数申请的堆内存的溢出位置,不可控,也就无法实现之前设想的任意地址重写的目的。
3. memcpy函数的奥秘
分析到这里,可能会有疑惑:
a. 为何该堆的大小只有4个字节,而之前写入的8个字节没有因为溢出出现异常,反而是再写入2个字节时就产生了异常?
b. 为何memcpy明明从样本倒数第二个字节0x26e开始拷贝,而之前的8个字节已经被写入到堆的前8个字节?难不成在memcpy函数之前,就进行了堆的写入操作?
要解决这些疑惑,就要去看看堆创建后是如何向里面写入内容的。由堆的栈回溯信息:
0:034> !heap -p -a 0x225ff000
address 225ff000 found in _DPH_HEAP_ROOT @ 6ff1000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
1794116c: 225feff8 4 - 225fe000 2000
74c08e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77451d4e ntdll!RtlDebugAllocateHeap+0x00000030
7740b586 ntdll!RtlpAllocateHeap+0x000000c4
773b3541 ntdll!RtlAllocateHeap+0x0000023a
74b10269 MSVCR100!malloc+0x0000004b
61bbb327 mfc100u+0x000bb327
67b83043 AviSplitter+0x00003043
可知AviSplitter+0×00003043之前的call指令就是进程创建该堆的地方:
AviSplitter+0x00003043
◆◆1
发表评论