0x00 前言
看蒸米师傅的一步一步学ROP做的笔记
0x01 具体分析
如果我们在获取不到目标机器上的libc.so情况下,应该如何做呢?这时候就需要通过memory leak(内存泄露)来搜索内存找到system()的地址。
这里使用了pwntools提供的DynELF进行内存搜索,首先需要一个leak(address)函数,:
1 | def leak(address): |
随后将这个函数作为参数再调用d = DynELF(leak, elf=ELF(‘./level2’))就可以对DynELF模块进行初始化了。然后可以通过调用system_addr = d.lookup('system', 'libc')
来得到libc.so中system()在内存中的地址。
要注意的是,通过DynELF模块只能获取到system()在内存中的地址,但无法获取字符串“/bin/sh”在内存中的地址。所以我们在payload中需要调用read()将“/bin/sh”这字符串写入到程序的.bss段中。.bss段是用来保存全局变量的值的,地址固定,并且可以读可写。通过readelf -S level2
这个命令就可以获取到bss段的地址了。
1 | mask@mask-virtual-machine:~/mzheng$ readelf -S level2 |
然后下面的解释直接引用蒸米师父的原话,解释的也很清楚:
因为我们在执行完read()之后要接着调用system(“/bin/sh”),并且read()这个函数的参数有三个,所以我们需要一个pop pop pop ret的gadget用来保证栈平衡。这个gadget非常好找,用objdump就可以轻松找到。
那么来找找咯,
1 | objdump -D level2 |cat -n |grep pop |
执行结果
1 | mask@mask-virtual-machine:~/mzheng$ objdump -D level2 |cat -n |grep pop |
找呀找,找呀找,找到三个连续的pop即可,那么接下来开始构造exp:
1 | # !/usr/bin/env python |