栈溢出基础实验三
TOC
环境
本次实验环境完全采用XP加vc6.0,原因我在上次已经说了,主要是由于user32.dll动态变化的原因,而且在xp上测试更简单,但是xp运行不了IDA pro7.0(不清楚是不是我自己的配置原因,或者是IDA没有做xp的兼容),这是最大的遗憾。
关于Win10的这个问题,我问了一下大佬究竟是怎么回事,主要是为了预防栈溢出漏洞。Win10现在还是在被微软维护中,存在的漏洞少之又少,但是Win10系统中存在的栈溢出漏洞还是有的,漏洞是要靠自己发掘的。
在上次的代码植入实验中,我们直接用IDA查出了栈中shellcode的起始地址。而在实际调试漏洞时,尤其是在调试Win10的程序,我们经常会发现有缺陷的函数位于某个动态链接库中,且在程序运行过程中被动态装载。这时的栈中情况将会是动态变化着的,也就是说,这次从调试器中直接抄出来的shellcode起始地址下次就变了。所以,要编写出比较通用的shellcode就必须找到一种途径能够自动定位到shellcode的起始地址。
一般情况下,巧妙地使用esp寄存器是比较好的选择。一般没经过优化的代码,正常的函数形式是如下这样的。
push epb ;只演示32位汇编,64位的也是如有雷同 |
当程序运行到A处时,栈空间由于代码注入已被破坏,但是ebp并没有遭到破坏,任然保存的是本函数栈的基址。在运行B时,没有被破坏的基址被赋值到esp,然后运行到C,由于栈被破坏了,所以pop出来的值是无效的,所以对于我们而言,ebp这时已经没有用了。
这时esp里的值就大有用处,此时esp指向的是返回地址的下一个地址,我们可以将shellcode覆盖于此,这样,无论地址怎么偏移,esp都始终指向它。
这时若是被覆盖(修改)返回的地址的指令恰好是jmp esp那就完美了。由于xp系统的动态库函数在内存的位置基本不变,所以可以直接在系统的动态库中寻找到这条指令在内存中的地址,然后用这个地址来覆盖返回地址,就一劳永逸了。
下面的程序就可以在user32.dll动态库中寻找到jmp esp指令的位置,FFEA就是jmp esp指令的机器码。
//当找不到相应指令时,程序会崩溃,这个怎么解决我也不清楚 |
在制作exploit的时候,还应当注意shellcode的退出问题,可以恢复成原来的值(在ollydby的调试下已获得),但是这样不确定性很大,指不定换了个环境那些从ollydby获得的值就改变了,所以直接调用ExitProcess函数是比较好的选择(exit函数没有,总是找不到入口地址)。还是用老办法获得入口地址。
|
下面是我写的shellcode。
|
再配上下面的工具。这是用C语言开发的,用Python开发会更快,但是XP好像装不了Python,所以用C语言写工具,反正原理都是一样的。
|
虽然退出有问题,但程序还是能达到预期目的。