8

Reading the book Hacking: The Art of Exploitation by Jon Erickson, I am trying to approximate the address of an environment variable SHELLCODE to exploit a program.

Every time I run getenv("SHELLCODE"); to get the location, the result is completely different.

Extract from my shell:

> for i in $(seq 10); do ./a.out SHELLCODE; done
SHELLCODE is at 0xff9ab3a3
SHELLCODE is at 0xffcdb3a3
SHELLCODE is at 0xffb9a3a3
SHELLCODE is at 0xffa743a3
SHELLCODE is at 0xffdb43a3
SHELLCODE is at 0xfff683a3
SHELLCODE is at 0xffef03a3
SHELLCODE is at 0xffc1c3a3
SHELLCODE is at 0xff85a3a3
SHELLCODE is at 0xff8e03a3

I understand that if the program name is modified or new environment variables are added, the position would be slightly different, but why does the location vary that much?

2
  • The getenv manual says it returns a pointer to a string containing the variable's value. Everything else is unspecified, so your kernel and/or compiler can stick the value wherever they want, as long as that pointer-promise stays true. I'm guessing the exact answer to this may be heavy wizardry and depend on various memory mapping implementation details and the phase of the moon. (I am not wizard enough to give you the exact answer.)
    – Anko
    Sep 13, 2014 at 19:36
  • "I understand that if the program name is modified or new environment variables are added, the position would be slightly different, but why does the location vary that much?" That's true in the simplest of all possible implementations, but it is certainly not required. Sep 14, 2014 at 4:25

1 Answer 1

13

What you describe is an anti-exploitation feature called Address Space Layout Randomization (ASLR). Basically, the kernel puts the very top address of a program's function call stack at a slightly different ("random") address every time the kernel loads the program's ELF file from disk. The addresses in argv and the environment variables, of which your shellcode is one, end up at a varying address with each program invocation.

ASLR is supposed to make it harder to exploit buffer-overflows and other stack-related vulnerabilities. The exploiter has to write code or do something to account for the varying addresses of variables and values on the function call stack.

Looks like you can disable ASLR by doing something like:

echo 0 > /proc/sys/kernel/randomize_va_space

as the root user. Since you explicit cite Ubuntu, the above command is different:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
1
  • Yes, that did the trick. I've noticed that the book author uses Ubuntu 10.04, which didn't yet have ASLR.
    – Janman
    Sep 14, 2014 at 8:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .