# Exploit Mitigations and Protections

## ASLR <a href="#docs-internal-guid-3ff3e511-7fff-5de3-f71b-3f7cae18fb8e" id="docs-internal-guid-3ff3e511-7fff-5de3-f71b-3f7cae18fb8e"></a>

Randomizes memory addresses (but not the addresses of instructions).

{% embed url="https://www.youtube.com/watch?v=MMm0I2Dj51A&list=PLhixgUqwRTjxglIswKp9mpkfPNfHkzyeN&index=37" %}

## Stack Canaries/Stack cookies

In a function, a stack canary is an 8-byte (or 64-bit, and 4-byte on 32-bit) value that is placed at the end of the stack. Then, at the end of the function, before the return, a check is made to determine if the canary still has the same value. If not, it’s determined that stack smashing has occurred.

It stops the function from returning, but might not protect from other side effects of the stack being overwritten.

However, note that compiler developers know about buffer overflows, so usually buffers are placed below local variables, and as close to the stack canary as possible, to prevent the variables from being overwritten.&#x20;

Also note that the canary starts with a NULL byte. This is because functions like strcpy can’t write NULL bytes, and so you cannot overwrite the canary with those functions.

However, on 32 bit it’s a NULL byte and 3 more bytes, which is able to produce 16 million total random values. Depending on how the program is run, you can try to exploit it 16 million times, and on one of those tries, you might be able to get the correct stack canary by chance.

{% embed url="https://www.youtube.com/watch?v=4HxUmbOcN6Y&list=PLhixgUqwRTjxglIswKp9mpkfPNfHkzyeN&index=36" %}

## Non-Executable Memory/DEP

It’s when CPUs make memory regions, such as the stack and the heap nonexecutable. This is done by either the NX bit, or if the cpu doesn’t support it, then it’s emulated via memory segmentation.

## PIE/Position Independent Executable <a href="#docs-internal-guid-172a3da1-7fff-08a6-7495-2df077122fad" id="docs-internal-guid-172a3da1-7fff-08a6-7495-2df077122fad"></a>

PIE/PIC makes it so that the addresses of the bytecode is not the same between executions. If it’s not enabled, then the location of main() is always the same, for example.

## RELRO

Since the Global Offset Table and Process Linkage Table contain function pointers, which are dereferenced to call those functions, then [being able to write to it will lead to arbitrary code execution.](https://systemoverlord.com/2017/03/19/got-and-plt-for-pwning.html)

There is a mitigation for this. Enter relocations read-only, or RELRO. It in fact has two levels of protection: partial and full RELRO.

### **Partial RELRO**&#x20;

During compilation, enabled with `-Wl,-z,relro`

* Maps the `.got` section as read-only, but not `.got.plt`
* Rearranges sections to reduce the likelihood of global variables overflowing into control structures.

### **Full RELRO**&#x20;

During compilation, enabled with `-Wl,-z,relro,-z,now`

Does the steps of Partial RELRO, plus:

* Causes the linker to resolve all symbols at link time (before starting execution) and then remove write permissions from .got.
* `.got.plt` is merged into `.got` with full RELRO, so you won’t see this section name.

**Only full RELRO protects against overwriting function pointers** in `.got.plt`. It works by causing the linker to immediately look up every symbol in the PLT and update the addresses, then `mprotect` the page to no longer be writable.
