Heap Spray(堆喷射)简介

0x00 Heap Spray(堆喷射)

堆喷射是在 shellcode 的前面加上大量的slide code(跳板指令),组成一个注入代码段。然后向系统申请大量内存,并且反复用注入代码段来填充。这样就使得内存被大量的注入代码占据。然后通过结合其他漏洞控制程序流,使得程序执行到堆上,最终将导致shellcode的执行。

常见的slide code 有NOP指令,还有一些类NOP指令,比如0x0c,0x0d等。它们的共同特点都是不会影响shellcode的执行。

0x01 Heap Spray原理

Q1 : 为什么需要在shellcode前面加上silde code?
如果想要成功执行shellcode,必须要准确的跳转到shellcode的第一条指令开始执行,如果整个空间都被填充为shellcode,精确跳转到shellcode的第一条指令的几率反而很低。如果在shellcode前面加上很长一段slide code,那么只要跳转到slide code范围内的任意地址,最后都能执行shellcode。

Q2 :为什么是 0x0c0c0c0c?
一是因为堆的分布不均衡(存在碎片),所以最先分配的一些堆块的地址可能是无规律的,但是如果大量的分配堆块的话,那么就会出现稳定的地址分布。也就是说内存中碎片过多,必须喷射到更高的地址才能使 exploit 更稳定。
通常在申请的内存超过200M(0xc8000000 > 0x0c0c0c0c),0x0c0c0c0c被含有shellcode的内存片覆盖,只要slide code能够击中0x0c0c0c0c的位置,shellcode最后都能被执行。

正常情况下的堆布局:

堆喷射后的堆布局:

堆喷射攻击技术

1. 覆盖函数指针地址

a. 申请200M内存,以sildecode+shellcode填充。
b. 覆盖函数指针地址为0x0c0c0c0c
c. 调用该函数的时候就会跳转到0x0c0c0c0c地址处,最后执行shellocde

2. 覆盖虚函数指针

a. 申请200M内存,以sildecode+shellcode填充。这个时候选择的slidecode不能是0x90。如果用0x90来填充,则虚表里面全是0X90909090,程序会跳转到0X90909090处执行,会导致crash。
b. 覆盖函数指针地址为0x0c0c0c0c
c. 调用该函数的时候就会跳转到0x0c0c0c0c地址处,最后执行shellocde 。

0xFF Reference

https://www.blackhat.com/presentations/bh-europe-07/Sotirov/Presentation/bh-eu-07-sotirov-apr19.pdf
https://blog.csdn.net/magictong/article/details/7391397