Actually, the title is a lie. We're not really going to discuss ASLR in that depth yet. We don't really need to. However, what we are going to do is explore the effects of ASLR on a diagnostic binary we used in the previous section.
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>
int main() {
puts("This program helps visualise where libc is loaded.\n");
int pid = getpid();
char command[500];
puts("Memory Layout: ");
sprintf(command, "cat /proc/%d/maps", pid);
system(command);
puts("\nFunction Addresses: ");
printf("System@libc 0x%lx\n", dlsym(RTLD_NEXT, "system"));
printf("PID: %d\n", pid);
}
ASLR Turned Off
First, make sure ASLR is turned off.
ubuntu@ubuntu-xenial:/vagrant/lessons/8_aslr/build$ echo 0 | sudo tee
/proc/sys/kernel/randomize_va_space
0
Now, play with the binaries in /vagrant/lessons/8_aslr/build/. You should notice that the addresses the objects are mapped at are more or less constant.
ubuntu@ubuntu-xenial:/vagrant/lessons/8_aslr/build$ echo 2 | sudo tee
/proc/sys/kernel/randomize_va_space
2
Before repeating the previous steps on the binaries again, take a look at the output from checksec.
ubuntu@ubuntu-xenial:/vagrant/lessons/8_aslr/build$ checksec *
[*] '/vagrant/lessons/8_aslr/build/1_reveal_addresses'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE
[*] '/vagrant/lessons/8_aslr/build/2_reveal_addresses64'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE
[*] '/vagrant/lessons/8_aslr/build/3_reveal_addresses_pie'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[*] '/vagrant/lessons/8_aslr/build/4_reveal_addresses64_pie'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
Notice that the last two have PIE enabled. PIE stands for Position Independent Executable. Do you notice any interesting about the results when running these binaries with ASLR turned on?