Loading
0

在ie8中利用ROP与Heap Spray利用反弹shell

接下来我们关心的是确保栈翻转按计划实施。我提到过这取决于你能在这个过程中访问到哪个寄存器的值。只需使用Windbg附加IE进程,然后传递足够多的A来溢出缓冲区(在我们的情况下为200),并观察哪个寄存器会被溢出数据控制。我这样做之后,发现EIP和EBP都被A溢出,EAX保持不变。这意味着我们需要使用`LEAVE;RET`gadgets。
还有很重要的一点就是,所有的ROP gadgets都是在MSVCR71.dll上搜素的,因为它不仅不受ASLR的保护,而且Alex也特意告诉我使用这个。
构造恶意输入
在这一节,我将参考下面的图表来寻找那些特定的ROP gadgets:

简单来说,ROP gadget只是一些共享内存模块(在我们的例子中是MSVCR71.DLL)中的一个内存地址,我们可以引用它来做一些操作,然后返回。有许多不同的工具可以用于搜索这些地址,Alex推荐了两种不同的选择:第一个叫做Skyrack,第二个叫做msfpescan带有正则表达式。这两种工具对于我想做的事来说都不大好用。于是我用Google找到了一个名为Ropper的开源工具。
所以,我使用了ropper。它很好安装,也很容易搜索复合指令,它会返回所有匹配的实例,而不是只返回一个。要使用的命令是:
```
ropper --file〜/ path / to / msvcr71.dll --search“INSTRUCTION;ret”
```
其中INSTRUCTION是你要搜索的指令。这里是我们需要的指令列表:
```
1.POP EAX,RET;
2.MOV EAX,DWORD PTR [EAX]; RET;
3.CALL EAX; RET;
4.POP EAX; POP EDI POP ESI; POP EBX; POP EBP; RET;
```
前三个可以很容易的通过Ropper找到。最后的指令有点困难。对于这一点,我发现了一个名为Fuzzysecurity的源,它使用了IE8的ROP链执行类似的漏洞利用。我试着跟随他的例子,但是我发现他使用了一个知名的通用ROP链,不过我决定不使用这个。但是,我注意到他找到了POP‘s并且列出了一些gadgets。唯一值得注意的是,他使用的gadgets包含五个POP指令,但我们调用的VirtualProtect只有四个参数。但这没有问题,因为我可以在最后添加一个虚拟的值,之后它会被弹出来。
接下来,将ROP gadgets留给栈翻转。如上所述,我们不能访问EAX - 我们知道在检查WINDBG溢出缓冲区时,发现只有EIP和EBP被覆盖。当我们控制EBP时只需要通过`LEAVE; RET`gadgets来翻转栈。我实际上能够使用Skyrack查找这个,因为如果只是搜索一个单独的LEAVE指令,就有很大的可能性它紧接着一个RET。 我使用WINDBG对地址进行反汇编来验证结果。
我们之所以要有POP(x5); RET,是因为ROP链本身的性质(译注:就是要弹出参数)。考虑以下这张图:

当我们从调用VirtualProtect返回时,我们伪造了一个栈帧。这意味着我们需要将VirtualProtect的所有参数POP出来,然后在这些POP之后,我们返回到栈中下一个地址。就是说当我们从VirtualProtect返回时,首先返回到`POP(x5); RET;`它负责删除参数,然后再返回到shellcode。
最初,我打算使用我自己手工生成的ROP链来演示,但是它没有工作。所以我决定采取Chandan的建议,使用Mona.py自动生成的ROP链。
在这里,我还想发出一些推荐给我的“幻影”地址。在课堂上,Alex给我们一些关于我们漏洞利用的结构的“提示”。首先,他说我们的缓冲区溢出应该包含栈翻转。接下来,我们得到一个模糊的提示,在我们的ROP链之前应该有一个地址:1)字节对齐或2)它可能是别的东西 - 我决定只使用Heaplib.js承诺的shellcode地址,因为为什么不呢?我不知道还应该放置什么在那里!最后的提示是,在我们的ROP链和shellcode之后,我们应该包括我们shellcode的“硬编码”地址。这对我没有意义,因为如果它正在执行ROP链,我们应该能够正确地击中shellcode,在我们调用VirtualProtect完成后,我们可以立即开始执行shell。所以基本上,每次我需要的“shellcode地址”使用的是0x0a0a2020。
最后我使用Metasploit来生成我的shellcode。 命令是:generate -t js_be,它提供了可以粘贴到Javscript函数中的shellcode。 一个重要的注意是确保shellcode可以被4整除,以便它可以正确排列。 我的是324字节长,可以被4整除,所以没有什么我需要做的。
未解决的问题
关于这个任务,我还有几个问题没能够弄清楚。下面,我将详细说明我的关注和我的结论,试图说服那些读者,其中至少有一些想法会被纳入这个领域。
1. 我不完全确定在缓冲区溢出时用什么去覆盖EIP的地址。我知道在幻灯片中,讨论了堆上对齐的地址,因为我们要么会命中NOP要么会命中我们的shellcode。但是,我不知道这是如何工作的,因为这个漏洞的整个点是获取和执行我们在堆上的代码。这意味着,如果我们命中的是NOPs或shellcode的开始(基本上除了pivot的一切)我们就会被卡住,因为我们没有移动ESP到我们的位置或改变保护。在与Alex讨论之后,他说用我们的堆栈枢轴覆盖EIP,这就是我所做的。(译注:不知道作者为啥会提出这个问题,估计是没能理解到精准堆喷射的意义所在。)
2. 我认为pivot的地址是我们最初溢出到EIP的地址,但这对我来说没有意义,因为发生在堆栈枢轴(LEAVE; RET)的操作代码只是移动ESP到EBP(译注:move the ESP into EBP???),但是如果我们仍然在栈上,我们就不会将其替换为堆上的地址。(译注:在ret返回之前就已经控制了ebp,可以直接更改成堆地址,为什么非要把EIP覆盖成pivot,实在看不懂作者咋想的。)所以我最终解决了这个问题,用shellcode和pivot的地址溢出初始缓冲区,因为我知道EIP会指向pivot。这以后通过WINDBG确认。
3. Alex基本上告诉我们在我们的ROP链之前插入一个地址,然后立即跟踪它。但是这是不明确的,它的目的是什么 - 我到现在仍然不知道。我获取的信息并没有表明这是必须要去做的。也许只是为了对齐?(译注:插入地址可以对齐???)ROP链后面的第二个地址应该是我们shellcode的“硬编码”地址。再次,我不明白为什么必须要这么做,而不是紧接着放置shellcode(译注:不放地址,你直接把指令ret了能执行吗?),但在这一点上,我盲目地采取了亚历克斯的建议。
4. 为什么我无法执行LEAVE;指令?我的主要想法是EBP有问题或有些东西指向无效的内存。我不是很确定到底是发生了什么,也没有能够解决它。

分页阅读: 1 2
【声明】:8090安全小组门户(https://www.8090-sec.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们:邮箱hack@ddos.kim,我们会在最短的时间内进行处理。