Address Space Layout Randomization (ASLR) is a security mechanism or technique implemented in Operating Systems.
Multiple kinds of cyber attacks relies on the ability to know/guess the memory address of data and functions of the specific process. ASLR prevents exploitation of memory corruption vulnerabilities by randomizing the location where executable are loaded into memory, this includes base address of the executable, positions of the stack, heap and dynamically loaded libraries. Effectiveness of ASLR is dependent on the fact that address space layout should remain unknown to the potential attacker.
On Linux systems ASLR supported from version 2.6.12, and enabled by default.
Too gain the protection on ASLR systems, applications should be compiled as Position Independent Executable (PIE) programs. PIE implements address randomness for executable. Before PIE feature, programs were loaded at the same base address and could not be placed at random locations. PIE is very similar to Position Independent Code (PIC) which is used for dynamic shared objects (*.so) and allows data and code relocation to a random offsets in memory.
After enabling PIE support in GCC, the program is compiled and linked as Position Independent Code using offsets and not absolute addresses.
PIE feature cannot be used together with the prelink feature for the same executable (the prelink implements randomization at build time rather than runtime)
Linux Kernel runtime configuration exposed to user space through the dedicated files in virtual file system, path /proc/sys/kernel
/proc/sys/kernel/randomize_va_space
To check current Linux setting
cat /proc/sys/kernel/randomize_va_space
Output can be one of the following:
0 - Disabled (can be applied if the kernel was booted with the norandmaps boot parameter).
1 - Randomize positions of the stack, virtual dynamic shared object (VDSO) page, and shared memory regions. The base address of the data segment is located immediately after the end of the executable code segment.
2 - Full Randomization, randomize the positions of the stack, VDSO page, shared memory regions, and the data segment. This is the default setting.
To configure ASLR
echo VALUE > /proc/sys/kernel/randomize_va_space
Or
sysctl -w kernel.randomize_va_space=VALUE
Application should be compiled with PIE enabled, specify the -fpie option to gcc when compiling and -pie option to ld when linking, for example:
gcc -O0 -std=c99 -pie -fpie -ggdb3 -o pie.out main.c
gcc -O0 -std=c99 -ggdb3 -o no-pie.out main.c
tip: To check if the executable was compiled with PIE
readelf -h ./EXECUTABLE | grep "Type:"
Output can be one of the following:
DYN (Shared object file)
EXEC (Executable file)
Lets see example of executables compiled with/without PIE, running on Linux System configured to ASLR disabled and level 2.
tip: If we'll inspect address of main function in both applications, we'll find that application with PIE contains offset and without PIE contains load address.
readelf -s ./no-pie.out | grep main
66: 000000000040052d 21 FUNC GLOBAL DEFAULT 13 main
readelf -s ./pie.out | grep main
66: 0000000000000775 23 FUNC GLOBAL DEFAULT 13 main
Lets see what happens to load address of shared libraries when dynamic linker resolves and loads dependencies of the applications being executed on system with ASLR disabled and level 2.
We'll use ldd utility which involves standard dynamic linker ld.so with the LD_TRACE_LOADER_OBJECTS environment variable =1, this cause to dynamic linker to inspect the program's dependencies, find and load them.
For each dependency, ldd displays the hexadecimal address at which it is loaded.