程序分析
利用ida打开程序会发现如下的情况:
主函数有个read函数有个溢出,看了程序的got表发现程序只有read函数并没有输出。
利用思路
考虑修改got表的中read地址的低字节,使它指向一个syscall地址。
我们先read在libc中的偏移是0xf6670,然后用ropper搜索libc中的syscall:
可以找到两个和read只有最低一字节不同的syscall的地址,这里我们选用0xf667e来进行利用。
我们有read函数因此可以从里面向内存中写入数据。用ROPgadget搜索其中的结果
没有可以利用的rop地址,由于不知道libc的基址因此没办法在libc中寻找rop,此时就考虑利用csu_init。
通过csu_init我们可以设置rdi,rsi,rdx的值,并且可以跳转到指定函数。
下面就是具体的利用思路了:
- 现修改got表中read的最后一个字节为0x7e,使之指向syscall
- 由于上一步中只读了一个字节rax返回1,所以记下来再次调用got[‘read’]就会系统调用write。利用此将got表中的地址显示,泄漏出libc的地址
- 返回main函数,由于main函数调用read时rax会清0,所以现在当got表中的read指向syscall时也会系统调用read。这样覆盖栈的返回地址为onegadget就能获得shell(注意由于我选onegadget需要rsp+30为0,所以栈溢出的时候多向写写几个0使其满足条件)
exp.py
1 | from pwn import * |