上面已经实验了缓冲区溢出是怎么产生的,于是想知道该怎么利用缓冲区溢出。
因为可以覆盖掉返回地址,所以可以把返回地址改成我们的代码的地址,于是返回的时候就可以跳到我们的代码那里去执行了。
这样遇到一个问题,就是无法确定我们的代码的确切地址~~(当然在调试器里能找到,但是不同的机器这个地址是不同的)因此直接跳转到我们的代码是不太可行的~
于是想办法将返回地址间接指向的能跳到我们可以控制的地址上去(*1),于是想到esp指向了我们可以控制的空间[堆栈],因此,将返回地址指向jmp esp,就可以回到我们的代码空间了。
在Win平台下是通过跳到kernel.dll或user32.dll这些一般不会变化的内存里的jmp esp一类的指令的地址上。
那如何找到这些地址呢?当然可以事先暴力搜索好了直接使用,但是这样通用性不高~~于是有了很多方法来获得这些个地址`参见很多文章~~[累啊]
给个图:绿色部分是我们可以控制的部分
用户堆栈 | kernel.dll的空间 |
返回地址 -> | jmp esp |
ShellCode<-ESP | |
还有一个方法,是用的 jmp ebx 来实现的,因为如果返回地址是错误的,那么就会引起错误处理(SEH相关)
开始的时候程序设置了SEH链,如果程序里出了错误,就会找到SEH链上的处理程序来处理。结构是这样的:
下一个SEH处理程序A |
SEH处理程序地址B |
因为SEH链也是保存在堆栈中的,属于我们可以控制的范围,因此我们可以修改SEH处理程序的地址,使得出错后程序跳到指定的地址上。同时EBX保存了下一个SEH处理程序(上面的A),于是如果上面的B指向JMP EBX 的话,出错后就能跳到A的位置上了。在A的位置放个 jmp 04,就能跳过B执行我们的CODE了~