Search code examples
cstackbuffer-overflowshellcode

Why is my C code throwing a segmentation fault even though the return pointer points to a memory address for seemingly valid shellcode?


I am trying to follow along with a tutorial about buffer overflow (Buffer Overflow Primer by Vivek Ramachandran). I am literally following his code, which works for him in the demo, and which has worked for me until this point.

The goal of the C program below is to assign shellcode for the exit system call to a variable, and then to replace the default return address for the main function, which points to __lib_start_main, with the memory address of the shellcode variable, such that the program executes the shellcode upon completing the main function, and then exits the program gracefully, with a value of 20 (as in execiting "exit(20)"). Unfortunately, the program ends with a segmentation fault instead. I am running this on 32-bit Linux Mint. I'm using gcc to compile the code, and have compiled it with the --ggdb and -mpreferred-stack-boundary=2 options, and I've tried both with and without the -fno-stack-protector option.

Here is the code:

#include<stdio.h>

char shellcode[] = "\xbb\x16\x00\x00\x00"
                   "\xb8\x01\x00\x00\x00"
                   "\xcd\x80";

int main(){

        int *ret;

        ret = (int *)&ret +2;

        (*ret) = (int)shellcode;

}
  1. It starts by defining a variable called shellcode which holds the shellcode.
  2. the main function is called and defines the ret variable, which is loaded into the top of the stack
  3. The memory location of the ret variable, plus 2 integer spaces, which represents the memory location of that is 8 bytes down the stack (the address of the return pointer) is assigned as the value of the ret variable.
  4. The memory address of the shellcode variable is written to the memory address represented by the value of the ret variable - ie.- the return address.
  5. When the function reaches the return instruction, it executes the shellcode, which is the exit function.

I have run this through gdb, and everything seems to check out: The memory location of the shellcode variable is 0x804a01c

At the start of the execution of main, the return value is at the 3rd hex-word and points to __lib_start_main

After executing ret = (ret *)&ret +2 , the value of ret in on the stack and is 8 bytes more than the beginning of the stack

After executing (*ret) = (int)shellcode , the return pointer (3rd hex-word) contains the address of the shellcode, rather than __lib_start_main

The program seems to move to resume execution at the memory address of the shellcode, but nevertheless ends in a segmentation fault.

Thanks in advance!


Solution

  • Adding the following option when compiling resolved the issue:

    -z execstack