堆溢出

今天上午终于把堆溢出看懂了~

一、windows下的堆

堆表:在堆的起始位置,用于索引堆块,分为空闲双向链表Freelist和快速单向链表Lookaside。

空表:128条,free[0]对应大于1024byte的堆块,其余free[i]为8*i大小的堆块。

堆块:前8个字节包含堆块的一些基本信息包括大小等,后面如果是空闲堆块还需要8个字节记录链表的前后地址。

二、堆表的操作

1.分配

选择合适大小的堆块分配 并找零,修改堆块状态值,从堆表中卸下,将地址返回堆申请者;修改双向链表。

2.释放

将堆状态改为空闲态,加入合适的双向链表。

3.合并

相邻的空闲表需要合并,修改堆块大小,修改双向链表。

三、DWORD SHOOT

双向链表操作时,会发生前向指针与后向指针的迁移,如果利用非法数据覆盖指针就会发生DWORD SHOOT。

具体操作可能会出现类似:

node->blink->flink=node->flink;

node->flink->blink=node->blink;

的语句,此时可以劫持进程。

四、P.E.B中的RtlEnterCriticalSection的利用

进程退出时会执行ExitProcess(),进而调用RtlEnterCriticalSection和RtlLeaveCriticalSection函数,如果将RtlEnterCriticalSection地址修改为shellcode地址,则可以劫持进程。

而恰恰我们可以利用双向链表的操作做到这一点,只要合适的堆溢出改变blink和flink分别为shellcode和RtlEnterCriticalSection的地址。

通过上面步骤,当进程执行ExitProcess()时就会进入我们事先布置好的shellcode中去。

 

补充:

不同操作系统对应的堆地址是不同的,可以通过ollydbg的M查看内存镜像,也可以通过查看每次成功分配堆地址后的EAX寄存器的值。

posted @ 2015-10-15 11:09  大魔王Faker  阅读(435)  评论(0编辑  收藏  举报