前言
前几天学习到了通过栈溢出弹窗,当时是入口地址是buffer
的地址,现在了解到有一个叫跳板的玩意
ESP
寄存器在函数返回后不被溢出数据干扰,且始终指向返回地址之后的位置
- 用内存中任意一个
jmp esp
指令的地址覆盖函数返回地址,而不用手工查出shellcode起始地址直接覆盖 - 函数返回后被重定向去执行内存中的这条
jmp esp
指令,而不是直接开始执行shellcode
- 由于
esp
在函数返回时仍指向栈区(函数返回地址之后),jmp esp
指令被执行后,处理器会到栈区函数返回地址之后的指令执行 - 重新布置
shellcode
,在淹没函数返回地址后,继续淹没一片栈空间,将缓冲区前边一段地方用任意数据填充,把shellcode
恰好摆放在函数返回地址之后,这样Jmp esp
指令执行过后会恰好跳进shellcode
这种定位shellcode
的方法使用进程空间里一条jmp esp
指令作为跳板
,不论栈帧怎么移位
都能准确地跳回栈区,从而适应程序运行中shellcode
内存地址的动态变化
正文
找出Jmp Esp
的地址
直接看源码
1 | //FF E0 JMP EAX |
首先加载user32.dll
动态链接库,算了看源码的注释吧👆,如果有错误的话麻烦指点一二。
这里的地址随便挑一个都可以,选第一个,尽量避免有0a
,0c
这些,因为这些是截断符。
寻找溢出位置
jmp esp
地址:760280f6
因为是在栈溢出的位置进行修改,所以首先要找出来是那个位置。
由于跳板是在函数入口处进入,不同于上一章是在尾部输入函数地址跳转,所以这次实验的password.txt
要输入更多的字符串来承载机器代码。
将程序拖入OD
,根据上次的分析,右下角堆栈窗口跟踪buffer
的地址,当程序执行到retn
时,观察运行位置,可以看出,是在5678
字符串的下一组4321
,所以就是要从此处进行修改。
将password.txt
在UltraEdit
编辑器中打开,快捷键Ctrl+H
切换十六进制编辑窗口,此次输入的字节刚好6行,24
组4321,其中有两组叛徒改为了1234,5678
。
刚才找出的地址是在5678
的下一组4321
首先根据大顶机
的缘故,逆序输入JMP ESP
的函数地址
接着,照常写入上一章中的弹窗机器代码。此次测试时候发现,我笔记本的MessageBox
的函数地址与我一开始测试的是相同的(我的笔记本每天都关机,此时获取到的地址是相同的,但是我写上一篇文章时使用台式机测试时,每次重启或关机在启动,地址都会发生变动),由于上篇文章是用台式机写的,所以截图的地址有所不同。
弹窗机器代码:33 DB 53 68 77 65 73 74 68 66 61 69 6C 8B C4 53 50 50 53 B8 60 10 07 76 FF D0
写入后,还剩几个字节,此时可以使用90
填充
最终修改完。
跳板运用
修改完password.txt
后,再次用OD
加载程序,重复之前的步骤,在堆栈窗口处观察buffer
的地址信息
当程序运行到retn
时,堆栈处停在了jmp esp
的地址处,再次F8
运行程序就清楚
此处就是刚才找到的jmp esp
的地址处
再次F8
运行程序,就会跳转到机器代码处
🔚
如果跳板的地址,真的会有存在一个是千载不变的地址,那么在写shellcode
时候就会很方便。不过要在多台机子测试过才知道。