HeapSpary技术及疑问
为什么heap spary要用0x0C0C0C0C这个奇怪的数字?
在讨论这个问题之前,先向小白介绍一下什么是 Heap Spary?
Heap Spary 又叫堆喷射,是在 shellcode 的前面加上大量的slide code(滑板指令),组成一个注入代码段。然后向系统申请大量内存,并且反复用注入代码段来填充。这样就使得内存被大量的注入代码占据。然后通过结合其他漏洞控制程序流,使得程序执行到堆上,最终将导致shellcode的执行。
Heap Spary 执行流程:
堆喷射将 shellcode放置在了堆中,在堆中执行代码。
使用浏览器程序打开我们的poc样本时,它会执行我们样本文件中的JavaScript代码。
控制程序eip,使其指向0x0C0C0C0C地址。
了解到 Heap Spary 后,再来讨论,为什么一定要用 0x0C0C0C0C 填充滑板指令?
(1)0x0C0C0C0C会被程序解释成 OR AL,0C 可以作为滑板指令(即执行此种指令不会对程序的后续行为产生影响),有人说为什么不使用0x90(也是滑板指令)呢?请看下一条。
(2)之前说过,我们的shellcode会被放到堆中去执行,也就是所谓的使eip指向0x0C0C0C0C这个地址,而0x0C0C0C0C这个地址从0计算的话,大概在192mb左右,但0x90909090就不言而喻了,需要申请的堆空间那就相当大了。
又有人会说为甚麽一定要让我们的eip指向0x0C0C0C0C呢?
堆喷射成功的前提是,我们填充的过程中恰好覆盖了一个虚函数指针,当该虚函数被调用时,先取得栈中的对象指针,通过对象指针取得虚表指针,然后在虚表内适当偏移处取得函数指针执行,过程如下:
因此根据上述过程,当我们使用“0c0c0c0c”作为slide code进行填充时,我们地址0x0c0c0c0c处也必须为“0c0c0c0c”,而正由于这个地址是自指向的,因此恰好执行“0c0c0c0c”命令直到执行shellcode。若为其他地址,将会导致指针跳转至其他地方,无法确保完成shellcode的执行。 也可以通过缓冲区溢出漏洞将EIP修改为0x0c0c0c0c就能跳转到该位置,然后完成shellcode的执行。
参考: