description |
---|
09/20/2023 |
Address Space Layout Randomization, or ASLR, can be explained as being libc
's equivalent of PIE.
Every time you run a binary, libc, the stack, and the heap
will get loaded into a different memory address within your address space.
Also, if ASLR is enabled, but Position Independent Executable (PIE) is not, you will notice that the ELF executable will not change places in memory, it will stay in the same place. But, if PIE is enabled, the ELF binary will be loaded into a new address each runtime.
In other words, ASLR alone will not change the position of the ELF binary.
However, there is one KEY difference between ASLR and PIE.
ASLR is a kernel-based protection. Meanwhile, PIE is a binary-based protection.
ASLR must be configured on the system, while the binary must be pre-compiled with the PIE memory protection set.
ASLR is enabled by default on all modern systems and embedded devices. So, it's best to practice with it enabled.
Also, another similarity is that you will NOT be able to get away with hardcoded function addresses in your exploit code like with PIE.
A reliable way of obtaining an ASLR address is by reading the GOT entry of a specific function.
Due to the nature of address randomization, libc
base addresses will always end in the hexadecimal characters 000
.
To disable:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
To enable:
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
Remember, this will go back to it's default value of 2
after every reboot.
There are a few different ways we can go about bypassing ASLR:
- Information Leaks ("Info Leaks")
- Partial RIP address overwrites + crash data
- Partial RIP address overwrite + brute force
- Use an address from a non-ASLR enabled module
An info leak is when you can extract meaningful information such as memory addresses from the ASLR-protected service or binary.
If you can leak any sort of pointer to code during your exploit, you more than likely bypassed ASLR because you have a reference to where things are in memory.
Using a single pointer, we can now calculate memory locations around us
Pointer to printf()
was leaked and has an address of 0xb7e72280
.
Looking at the libc
library, we can see how far printf()
is from system()
and it is -0xD0F0
-bytes away from printf()
.
So, all we need to do is subtract the address and it's offset and we will have a fixed address for system()
.
0xb7e72280 - 0xD0F0 = 0xb7e65190
system() address