TL;DR
Address Space Layout Randomization (ASLR) is a security technique that makes it harder for attackers to predict the location of key data in memory. This guide explains common techniques used to bypass ASLR, allowing exploitation of vulnerabilities even with this protection enabled.
Understanding ASLR
ASLR randomizes the base addresses of libraries, the stack, and the heap each time a program runs. This means an attacker can’t rely on fixed memory locations for functions or data structures. However, information leaks can reveal these addresses.
Bypassing ASLR: Techniques
- Information Leaks
- Stack Leaks: Exploiting vulnerabilities like buffer overflows to read values from the stack. These values often contain partial addresses or offsets useful for calculating base addresses.
- Heap Leaks: Similar to stack leaks, but targeting heap memory. Useful for bypassing ASLR on libraries loaded at random addresses.
- Library Base Address Leaks: Reading the address of a known function within a library (e.g.,
putsin glibc). This provides a base address for that library.
ROP involves chaining together small snippets of code (‘gadgets’) already present in the program or loaded libraries to perform desired actions. ASLR bypass is crucial for ROP as it requires knowing the addresses of these gadgets.
- Finding Gadgets: Tools like
ROPgadgetcan search for useful gadgets within executables and libraries.ropgadget --binary /path/to/executable --string "pop rdi; ret" - Building a ROP Chain: Constructing a sequence of addresses to execute the desired functionality. Requires accurate address calculations after bypassing ASLR.
On 32-bit systems, the address space is smaller, making brute-forcing possible in some cases. This involves trying different base addresses until a successful execution path is found.
- Address Space Size: The effectiveness of brute-force depends on the size of the address space (e.g., 4GB for 32-bit, much larger for 64-bit).
- Entropy: The amount of randomness in ASLR affects the difficulty of brute-forcing.
Some libraries use relocation tables to resolve addresses at runtime. Partial overwrites or manipulation of these tables can lead to controlled address changes, bypassing ASLR.
Filling the heap with predictable data patterns to increase the chances of landing code in a known location. Less effective against modern ASLR implementations.
Practical Example: Leaking libc Base Address
Let’s say you have a buffer overflow vulnerability and want to leak the base address of libc.
- Identify a Leak Function: Use a function like
putsorprintf. - Craft Payload: Overflow the buffer, overwriting the return address with the address of your chosen leak function (e.g.,
puts). - Run and Analyze: Execute the program. The output will show the address of
putsat runtime. - Calculate libc Base Address: Subtract the offset of
putswithinlibcfrom the leaked address.libc_base = puts_address - puts_offset
Mitigation
- Strong ASLR: Using a larger entropy pool for randomization.
- Position Independent Executables (PIE): Randomizing the base address of the main executable itself, not just libraries.
- Control-Flow Integrity (CFI): Preventing attackers from redirecting control flow to unexpected locations.