SEED缓冲区溢出实验笔记——Return_to_libc
参考:http://www.cis.syr.edu/~wedu/seed/Labs_12.04/Software/Return_to_libc/
http://drops.wooyun.org/tips/6597
Bypassing non-executable-stack during exploitation using return-to-libc by c0ntex | c0ntex[at]gmail.com
ROP轻松谈
《程序员的自我修养》(虽然我没看完,但是对于理解这一切很有帮助)
在已经了解了缓冲区溢出的基本原理后,使用R2Libc方法需要获得最关键三个参数:system()、exit()、“/bin/sh”的地址,其中system()和exit()是libc.so中的函数,我们想要调用system并传入“/bin/sh”,并且返回到exit()的地址正常退出,以免留下错误日志。
要取得字符串的地址,教程中给出了一个方法,即通过自己程序的环境变量的地址来寻找漏洞程序的SHELL环境变量地址,因为他们的地址相近。但是程序的环境变量地址往往难以猜测,不如利用libc.so里的字符串,采用gdb如下指令可以查找到该地址。其中0xb7e5f430是system的地址。
通过反汇编正常的system()调用(自己写一个例子程序),可以从下图看出,是将参数字符串”/user/bin”的地址入栈来进行传递参数的。调用完system()后,程序同样会返回。正常调用函数是使用call命令,该命令首先将下一条指令的地址入栈,然后再跳转至目标地址执行。所以,我们在让程序的eip直接指向system()时,需要构建所谓的“伪栈”(fake frame)才能让溢出正常的进行,即栈让中依次存储”/usr/bin”地址、返回地址(exit()的地址)。esp指向的是返回地址。如图所示。为什么是这样的呢?其实,在溢出之后,对比参考图(b)就容易知道,上述要求的栈结构和调用call命令之后是一样的,故所谓的fake frame就完成了;而我们溢出是直接让eip指向了system,没有调用call。需要注意,溢出让ebp原来的值丢了,破坏了栈帧的结构。
下面来看一看细节。反观我们溢出后程序的栈,在执行leave、ret命令后,ebp变为原值,esp指向原来的参数位置。通过调试溢出的程序,发现程序转到system()地址后,没有像一般函数那样push ebp,所以esp继续指向0xbfffff200地址,即溢出前存放参数的位置。同样可以看到,0xb7e5f49b直接返回ret,并没有leave指令,而ret指令功能就是pop eip(这样的说法是否准确?),所以在调用完system()后eip会变成0xbfffff200存放的内容,故教程中的fake_ret位置是正确的。从0xb7e5f437指令可以看出,对参数的引用就是根据esp的偏移,将0xbffff204的内容放到了esi中。虽然ebp被我们“丢掉”了,但是system()没有用到ebp。
接着一步步的执行,会发现程序跳转到了不知名的地址0xb7e5ee70中,并且再也不会回到之前的f4**的地址,但是,最后仍然会使用0xaaaaaaaa返回,即调用system()前设置的返回地址(过程中都发生了什么?)。但是,如果把system看做一个黑盒的话,这么做确实可以成功的攻击。
其实在实验的时候,我花了很久才理解为何这样构建所谓的fake frame是正确的。原因在于分析问题的粒度:我一步步汇编跟进了system函数,而没有从调用函数黑盒的角度来理解。这也算是走了弯路的收获吧。
漏洞程序代码:
By Ascii0x03
最新文章
- 运用php做投票题,例题
- thymeleaf常用标签
- Unity 3D 基础知识方法
- hdoj 2039 三角形
- [水煮 ASP.NET Web API2 方法论](3-6)万能路由
- SQL初级第二课
- 2.使用Package Control组件安装
- (Relax 数论1.8)POJ 1284 Primitive Roots(欧拉函数的应用: 以n为模的本原根的个数phi(n-1))
- NOI2013 Day2
- Android 开发笔记___滚动视图__scroll view
- 不停服务,动态加载properties资源文件
- JVM--01
- 通用导出excel
- WEB 设计规范
- nodemailer + express + h5 拖拽文件上传 实现发送邮件
- 利用PyMySQL库连接数据库
- 前端表单验证常用的15个JS正则表达式
- 洛谷P3348 [ZJOI2016]大森林(LCT,虚点,树上差分)
- SVN提交文件失败:系统找不到指定路径
- 通讯协议(三)Protocol Buffers协议
热门文章
- amazeui-js插件-ui增强-日期组件如何使用(把实例做一下)
- ueditor在表单中的提交
- Android菜鸟的成长笔记(24)——Android中的振动器
- 【9210】找礼物(char* num[2000]的使用 get char num[i] = new char[1000])
- AsyncTask下载图片
- Asp.net压缩网站中的文件
- PHP设计模式——迭代模式
- [Cordova+Sencha Touch] 移动开发1 sencha 2.4.0 + 在 安卓2.3.6上使用报错 - has no method 'bind'
- Real-time storage area network
- python 获取字典值