JMP ESP =>SEH(CALL EBX)

来源:互联网 发布:剑网三成男捏脸纯数据 编辑:程序博客网 时间:2024/06/04 18:21
首先你要知道怎么利用JMP ESP的方式
其利用格式是ORS,这里O=NOP,R=RET(jmp esp的地址),S=ShellCode。就是把缓冲区一直覆盖成NOP(空指令,什么都不做),直到原来的EIP位置时,J
JMP ESP,紧跟后面才是我们的ShellCode。 
这种方式执行到ShellCode的原理:正常情况下,函数返回时,RET,等于POP EIP,即回复原来PUSH的EIP,从而回到函数调用前的程序。但在这里,我们把保存的EIP的值覆盖了,改写成了jmp esp的地址。这样,POP EIP后,EIP = jmp esp的地址,而堆栈指针ESP会往下走,指向ShellCode的开始。程序继续执行,此时EIP里的内容是jmp esp,系统执行jmp esp,就正好就跳到我们的ShellCode的地方了。 

JMP EBX利用方式 
其利用格式是OJES。O= NOP, J = Jmp 04,E = jmp ebx的地址,S = ShellCode。

JMP EBX的利用过程就是利用SEH链来执行我们的Shellcode. 
这里的J和E的位置是关键,E是在出错处理的入口位置,而J在其前面。 
在第一种方式中,我们知道将返回地址覆盖成另一个地址。但如果是个无效的地址呢?那里指向的数据或许不能读,或许不能执行,那会怎么样呢?其实相信大家都遇到过,那就是系统会弹出个对话框报错,我们点确定,就会终止运行。
这是因为作为一个系统级的程序,内部有健全的出错处理机制。也就是大牛们所说的SEH链,简单的说,如果运行时有错误产生,windows就会跳到一个专门处理错误的地方,对应不同的错误,执行不同的代码。上面执行的代码就是弹出个对话框报错。
所以这里我们故意把返回的地址覆盖成一个错误的地址。这样出错时,windows就会跳到处理错误的入口,而ebx指向SEH-4,那我们把错误入口处覆盖为jmp ebx的地址,就会跳到前4个字节,然后在这里我们写入jmp 04,往后跳4个字节,正好跳过覆盖的JMP EBX,达到我们的ShellCode! 

把JMP ESP转化为JMP/CALL EBX

为什么要考虑把JMP ESP方式转换为JMP EBX方式 
其实最大的好处是通用性,JMP ESP在各个系统,各个补丁版本上是不一样的,这样就会造成不同的系统不通用;而JMP EBX有一个NT/ 2000/XP/2003所有版本的通用地址!ShellCode可以想办法写成为通用的版本,这样只要漏洞本身的入口地址相对位置一样,就可以实现真正的通用。
但是在实际中,有许多的expoit,利用的却是JMP ESP方式,比如说isno写的.printer漏洞exploit,和flashsky写的RPC远程溢出exploit,这会导致问题,特别是对RPC来说,如果地址错误,就会导致RPC服务的崩溃,从而不能变换地址作再一次的攻击,要等到对方重启后,才能再试。这样就算是知道对方是2000系统,运气不好,都可能要试5次后才能成功(sp0 – sp4)…. 
.而如果有了通用的版本,就可以保证无论对方是什么系统,都可以一次成功! 

如何把JMP ESP方式转换为JMP EBX方式 
牛人们用的方法,比较直观和清晰,当然技术含量也就比较高。他们一般是用Softice加载VUL的程序,反汇编ZXCV!@#$%^&*(,很困难的,需要大量的经验。 
对于菜鸟来说还是推荐ww0830的方法

(转)WW0830的办法:笔者经过亲自试验,发现了个比较简单的方法(相对于直接分析服务),把已有的jmp esp方式,改进为jmp ebx方式。其思路是,先利用jmp esp的攻击程序,在jmp esp代码后,跟上“\xeb\xfe”,这句即jmp –1。实行模拟攻击后,在被攻击机上调出softice,就会发现停在“\xeb\xfe”这句。这时,我们查看其fs:0000的值,它里面存的就是异常处理的入口地址!这时,我们计算那个值离现在的距离,就轻松知道要填充多少达到异常处理入口了。