Protecting Linux System by Address Space Layout Randomization

  • What is Address Space Layout Randomization?

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)

  • What should be configured in Linux Kernel at 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

  • What about the Application?

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)

  • Example #1

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

  • Example #2

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.