《0day安全》—— 3.2 定位shellcode

在2.4节的实验中,我们用shellcode在内存中的起始地址覆盖返回地址。但是,由于动态链接库的装入和卸载等原因,Windows进程的函数栈帧很有可能会发生“移位”,所以shellcode在内存中的地址是会动态变化的
  因此,用2.4节当中的方法覆盖返回地址是不靠谱的。我们要在程序运行时能够动态定位栈中的shellcode。
  于是我们发现这样一个细节,函数在返回时,返回地址被弹入EIP,而ESP则指向返回地址的后一个位置。那如果我们用 "jmp esp" 的指令地址覆盖返回地址,在函数返回时,该指令得到执行,程序就会跳回到栈中ESP所指的位置,然后从这里开始,我们填入shellcode,岂不是可以为所欲为了。
  使用进程空间里的一条 "jmp esp" 指令作为跳板,不管栈帧怎么“移位”,程序都会精确地跳回栈区执行我们的shellcode。
  那么,怎么获取 "jmp esp" 指令的地址呢?
  通过OllyDbg的插件OllyUni.dll可以获得整个进程空间中的各类跳转地址。值得注意的是 OllyUni.dll 插件在OllyDbg 2.0 中使用不了,1.1可以。
  1. 下载OllyUni.dll 插件,并把它放在OllyDbg目录下的Plugins文件夹中
  2. 重新启动OllyDbg,调试exe,在代码框内右键,选择"Overflow Return Adress" , 选择"ASCII overflow returns" ,选择"Search JMP/CALL ESP"
  3. 等待Search完成,点击 "L" 按钮,查看搜索结果

《0day安全》—— 3.2 定位shellcode_第1张图片
jmp_esp1.png

4. 选择"JMP ESP in kernel32.text" 的地址0x76708BD5来覆盖返回地址
  接下来,我们就可以构造shellcode,如下:

《0day安全》—— 3.2 定位shellcode_第2张图片
2016-11-30 15-25-51.png

其中,MessageBoxA与ExitProcess函数的入口地址获取方法在2.4节中提到过,不同的是MessageBoxA是user32.dll的导出函数,ExitProcess是kernel32.dll的导出函数。
  把shellcode的代码编译运行,用OllyDbg加载可执行文件,在代码区选中所需代码,右键,选择"Copy",选择"To file",可以将汇编代码对应的机器码提取出来

《0day安全》—— 3.2 定位shellcode_第3张图片
2016-11-30 15-39-15.png

然后按照机器码逐字填入password.txt.

《0day安全》—— 3.2 定位shellcode_第4张图片
2016-11-30 15-19-16.png

利用OllyDbg调试,在verify_password函数返回处加断点,程序运行到此处,会跳转到地址0x76708BD5处执行"jmp esp"指令,如下图:

《0day安全》—— 3.2 定位shellcode_第5张图片
2016-11-29 17-07-18.png

执行完该指令后,继续F8单步,发现程序跳回到了我们的shellcode部分。如下图:

《0day安全》—— 3.2 定位shellcode_第6张图片
2016-11-29 17-07-56.png

注:至于shellcode的执行结果,上一次在2.4中也提到过,由于我自己计算出来的MessageBoxA的入口地址提示出错,所以代码没法往后进行,暂时还没有运行结果截图。

你可能感兴趣的:(《0day安全》—— 3.2 定位shellcode)