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);
}
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$ ./1_reveal_addresses
This program helps visualise where libc is loaded.
Memory Layout:
08048000-08049000 r-xp 00000000 00:28 161
/vagrant/lessons/8_aslr/build/1_reveal_addresses
08049000-0804a000 r--p 00000000 00:28 161
/vagrant/lessons/8_aslr/build/1_reveal_addresses
0804a000-0804b000 rw-p 00001000 00:28 161
/vagrant/lessons/8_aslr/build/1_reveal_addresses
0804b000-0806c000 rw-p 00000000 00:00 0 [heap]
f7e0f000-f7e10000 rw-p 00000000 00:00 0
f7e10000-f7fbf000 r-xp 00000000 08:01 256310
/lib/i386-linux-gnu/libc-2.23.so
f7fbf000-f7fc0000 ---p 001af000 08:01 256310
/lib/i386-linux-gnu/libc-2.23.so
f7fc0000-f7fc2000 r--p 001af000 08:01 256310
/lib/i386-linux-gnu/libc-2.23.so
f7fc2000-f7fc3000 rw-p 001b1000 08:01 256310
/lib/i386-linux-gnu/libc-2.23.so
f7fc3000-f7fc6000 rw-p 00000000 00:00 0
f7fc6000-f7fc9000 r-xp 00000000 08:01 256309
/lib/i386-linux-gnu/libdl-2.23.so
f7fc9000-f7fca000 r--p 00002000 08:01 256309
/lib/i386-linux-gnu/libdl-2.23.so
f7fca000-f7fcb000 rw-p 00003000 08:01 256309
/lib/i386-linux-gnu/libdl-2.23.so
f7fd4000-f7fd6000 rw-p 00000000 00:00 0
f7fd6000-f7fd8000 r--p 00000000 00:00 0 [vvar]
f7fd8000-f7fd9000 r-xp 00000000 00:00 0 [vdso]
f7fd9000-f7ffb000 r-xp 00000000 08:01 256300
/lib/i386-linux-gnu/ld-2.23.so
f7ffb000-f7ffc000 rw-p 00000000 00:00 0
f7ffc000-f7ffd000 r--p 00022000 08:01 256300
/lib/i386-linux-gnu/ld-2.23.so
f7ffd000-f7ffe000 rw-p 00023000 08:01 256300
/lib/i386-linux-gnu/ld-2.23.so
fffdd000-ffffe000 rw-p 00000000 00:00 0 [stack]
Function Addresses:
System@libc 0xf7e4ada0
PID: 4452
ubuntu@ubuntu-xenial:/vagrant/lessons/8_aslr/build$ ./4_reveal_addresses64_pie
This program helps visualise where libc is loaded.
Memory Layout:
555555554000-555555555000 r-xp 00000000 00:28 158
/vagrant/lessons/8_aslr/build/4_reveal_addresses64_pie
555555754000-555555755000 r--p 00000000 00:28 158
/vagrant/lessons/8_aslr/build/4_reveal_addresses64_pie
555555755000-555555756000 rw-p 00001000 00:28 158
/vagrant/lessons/8_aslr/build/4_reveal_addresses64_pie
555555756000-555555777000 rw-p 00000000 00:00 0 [heap]
7ffff780a000-7ffff79c9000 r-xp 00000000 08:01 2068
/lib/x86_64-linux-gnu/libc-2.23.so
7ffff79c9000-7ffff7bc9000 ---p 001bf000 08:01 2068
/lib/x86_64-linux-gnu/libc-2.23.so
7ffff7bc9000-7ffff7bcd000 r--p 001bf000 08:01 2068
/lib/x86_64-linux-gnu/libc-2.23.so
7ffff7bcd000-7ffff7bcf000 rw-p 001c3000 08:01 2068
/lib/x86_64-linux-gnu/libc-2.23.so
7ffff7bcf000-7ffff7bd3000 rw-p 00000000 00:00 0
7ffff7bd3000-7ffff7bd6000 r-xp 00000000 08:01 2067
/lib/x86_64-linux-gnu/libdl-2.23.so
7ffff7bd6000-7ffff7dd5000 ---p 00003000 08:01 2067
/lib/x86_64-linux-gnu/libdl-2.23.so
7ffff7dd5000-7ffff7dd6000 r--p 00002000 08:01 2067
/lib/x86_64-linux-gnu/libdl-2.23.so
7ffff7dd6000-7ffff7dd7000 rw-p 00003000 08:01 2067
/lib/x86_64-linux-gnu/libdl-2.23.so
7ffff7dd7000-7ffff7dfd000 r-xp 00000000 08:01 2051
/lib/x86_64-linux-gnu/ld-2.23.so
7ffff7fea000-7ffff7fed000 rw-p 00000000 00:00 0
7ffff7ff6000-7ffff7ff8000 rw-p 00000000 00:00 0
7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00025000 08:01 2051
/lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffd000-7ffff7ffe000 rw-p 00026000 08:01 2051
/lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0
[vsyscall]
Function Addresses:
System@libc 0x7ffff784f390
PID: 4446
Now, turn on the ASLR.
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?