Week 3 Flashcards
What is a non-executable stack?
This is a stack does not allow for the execution of any code. If an attacker injected their own shell code into the buffer, for example, they could not execute it simply by jumping back to it.
What is Address Space Layout Randomization?
It makes it so that every time a program is run, a different set of memory locations is used so the hacker can’t just learn the layout and then run the program again to attack it.
What do you do (as an attacker) if you can’t inject your own code?
You use existing code. Programs typically rely on libraries, so you can use the program’s code or code from its libraries.
Each piece of existing code you leverage is called a gadget. What you can do is chain gadgets together so that you can create your own new execution process/function.
What are Stack Canaries?
They are provided by the compiler. They make sure that buffer overflow attacks are harder to perform.
The compiler puts data in between the control data and local variables. If an adversary passes the canary, it will overwrite it. The compiler can detect if the canary was overwtitten before it returns. If it’s been tampered with, it segfaults.
The attacker can still overflow and crash the program, but he can’t take over control.
We can’t add a canary to every pointer/buffer because it’s to expensive to verify it constantly.
What happens if an attacker knows the canary’s value?
He can replicate it so it looks untouched. BUT, we have 3 defense mechanisms for this.
1) We can use null terinator characters for the canary so that when the attacker tries to replace the canary value of say 4 null terminating characters, it writes the firsty and strcpy stops since it’s instructed to stop at the first null character. So, the attacker can’t replicate the canary exactly. Memcpy can get around this though since it doesn’t stop at the null character and copies all values up to a certain number, so it’s not fool proof.
2) You can randomly generate the canary on every route. Since it’s random, the attacker will find it hard to figure out (reliably) what the canary is. Every time he is wrong, the program will crash and he needs to start again. But, starting again just gives a new random canary, so he has the same low probability of succeeding. However, if the attacker uses string format specifiers, he can print the values of the stack, learn the canary, and then take over by replicating the canary.
3) You can return an XOR of the RA and EBP which makes it harder for the attacker to replace the canary. The attacker would have to change the RA and EBP to replicate the canary. This is still doable though. It’s just more annoying for the attacker.
What is Bounds Checking?
It makes sure that we don’t have more data than we can fit in our buffer. But, if it’s done inefficiently, it will take too much time to do and can’t be used.
What is an Electric Fence?
It’s a memory page where if you try to access it, the program just crashes.
They are onlty useful for the heap and are not useful for the stack. It only works on dynamically allocated memory.
How does an Electric Fence work?
You allocate your memory pages for your data, and then what we do is we allocate a memory page that serves as an electric fence.
The property of the electric fence is we use the mprotect system call that makes sure that the page has no access privileges whatsoever. So, if the CPU is copying data, doing Loads or Stores, the second it tries to access an address in this memory page, it will trigger a segfault.
SO, if we call malloc and allocate another buffer, (the upper one), we give it another electric fence.
What are the pros and cons of the Electric Fence?
PROS:
It works well in terms of performance since it’s done by hardware.
Great for debugging software.
CONS:
It causes the program to crash in the event of a buffer overflow.
It doesn’t really work with the stack.
They are not efficient in terms of space. Pages have a minimum size (usually 4kb) which is too big if you’re going to have a lot of fences.
What is a Fat Pointer?
This is another option for bounds checking. Typically, our current pointers consist of one memory word (32-bits in a 32-bit architecture).
Fat Pointers are pointers that have metadata. They have 3 memory words and include the start address, end address, and the current address being pointed to.
What is an example of a Fat Pointer?
For simplicity, assume the return memory address starts at 0 and goes to 3. The current address we are pointing to points to 0, the start of the memory region we were allocated. We then have a pointer we create called x + 1 = y.
It inherits the space of x, and the current position will be 1. If we try to access X[3], this will be okay because it’s within the limits.
But if we try to access Y[3] that isn’t okay because it’s technically going to be the current of Y which is 1 + 3 = 4 which is greater than the end offset which is 3, so our check fails.
What is the drawback of using Fat Pointers?
Pointers in general are everywhere, so adding this to all pointers ias way too much space eaten up by fat pointers.
Fat pointers also don’t play nicely with legacy libraries and other languages. They aren’t in older code or other languages so they cause problems.
With Fat Pointers, updates are no longer atomic, meaning that id two threads are accessing a pointer, one thread can modify the start of it, while the other is modifying the index we are looking at. This means you could access out of bounds which shouldn’t be possible.
What are Low Fat Pointers?
They have the flavor of encoding metadata in the pointer, but they fit in 64 bits.
What is another term for Data Execution Prevention?
It’s also called setting the non-executable bit.
What is Data Execution Prevention or Setting the Non-executable Bit?
This is where we make the stack completely non-executable. This prevents the attacker from executing the code they injected into the stack.
Memory pages come with three permission bits: Read, Write, Execute. We are setting the execute bit to 0.
The Idea: memory pages should be writeable XOR executable.