利用缓冲区溢出漏洞,需要一段能生成缓冲区的代码,且这个缓冲区能被填入到易受攻击的程序中。这个缓冲区应当包括期望的shellcode,并且应该重写堆栈中的返回地址,以使shellcode能够执行。这意味着必须提前知道shellcode的实际地址,此外还必须重写堆栈中用来存储返回地址的4个字节。即使知道shellcode的正确地址,但重写返回地址不正确,程序也会崩溃,达不到缓冲区漏洞利用的效果。解决这个问题主要有两种方法
一、NOP sled方法
NOP是一条不做任何操作的单指令,对应的十六进制编码为0x90。这里NOP将被用作欺骗因子。通过创建一个大的NOP指令数组并将其放在shellcode之前,如果EIP返回到存储NOP sled的任意地址,那么在达到shellcode之前,每执行一条NOP指令,EIP都会递增。这就是说只要返回地址被NOP sled中的某一地址所重写,EIP就会将sled滑向将正常执行的shellcode
二、用具有预期返回地址的实例一个一个地填满整个缓冲区,这样只要这些返回地址中有一个地址重写了真正的返回地址,shellcode就会执行。
即使使用了上述两种方法,为了推测出真正的返回地址,必须知道缓冲区在内存中的大概位置。估计存储位置的一种方法是利用当前堆栈指针做指导,通过从堆栈指针中减去一个偏移量,可以获得任何变量的相对地址。