【3.27】学习笔记--再战ROP
继上一次做了一半实验后发现系统居然是x64的后。。。重新开始实验。前面重复部分不再赘言。
又是一番重复,终于出现
崩溃地方一样。
使用offset指令获得偏移地址
此处计算出返回值覆盖点为140后面。也即是构造A*140+ret的地址就好。
然而gdb调试时跟实际环境还有区别。也即gdb调试时buf在内存中的位置会受到影响。
安装蒸米前辈的文章中的意见于是决定使用core dump。
(简单解释下core dump:中文翻译叫做核心转储。也即程序在崩溃时会记录下来关键信息用以分析)
开启core dump 并让其输出信息输入到tmp里。此处sh -c 也即命令从‘ ’中执行。
所谓开始core dump其实是不对的,默认只是把大小上限设置为了0.第一条指令也就是将其设置为无限大。
此时可以计算出buf的真正地址为0xbf9bdb20
此处解释下gdb x指令即以16进制表示变量。 数字即表示多大的范围。 后续可以跟u,s(字符串),i(指令)
$表示寄存器 之所以此处是esp-144需要好好计算一下。
首先esp指向的地址是栈顶,而第一个进栈的数据是栈底。栈底是高地址,栈顶是低地址。而栈又是从高地址向低地址伸展的。
借用下别人的图片可知因为140的字节溢出再加上4个字节的返回值。所以esp-144即使buf的地址。
看来还是有问题存在,暂时先
贴上代码
需要注意的是p32即将ret地址转换为32位可以使用的地址。也即转换为字符串
u32即反之。
然而出现了问题
实验到这里又出现了问题....解决了半天解决不了。于是先继续看教程了。
下面开启DEP保护buf则无法执行。于是就使用Ret2libc方法进行绕过
方法即加载level2 然后在main函数下断点。在使用print system 打印出来system函数在内存的位置,然后再使用print __libc_start_main来打印出lib.so的起始地址。最后通过find命令 在libc.so的起始地址到220000的范围内寻找“/bin/sh”的位置。
exp如下:
接着再次打开ASLR保护。此时就该使用ROP了!
思路如下:
因为程序本身在内存中是不随机的。所以我们只要找到lib.so泄露出来的某些函数的地址,然后根据地址计算偏移量计算出system地址和/bin/sh的地址。紧接着参照ret2libc既可。
使用objump查询
发现其中使用了[email protected] [email protected]函数。
通过[email protected] 我们可以把write()函数地址得到,也就是write.got。因为linux使用了延时绑定的机制,所以当调用[email protected]时,系统会将真正的wirte()地址link到got表中。因为system() 和wirte()函数在lib.so中的offset是不变的。所以就可以计算出system的地址了。
ps:
plt表为内部函数表,got表为全局函数表。plt表跟got表对应。