Stack Canaries
aka stack cookies
The idea is that as long as we can put a secret value in between the stack variables and the return address, then we can check it before we return to the next instruction.
This is a mitigatioln of buffer overflow attacks
PREAMBLE
mov rax, qword fs:[0x28]
mov qword [rbp-0x8], rax
BEFORE RETURN
mov rdx, qword [rbp-0x8]
xor rdx, qword fs:[0x28]
je 0x40079f
call _stack_chk_fail
fs is a special storage area which is difficult to access even if you have a vulnerability like information disclosure.
rbp-8 is right where local variables end
Just before returning, we'll pull that value back out from rbp-8 in stack, XOR it with original value in fs
If they are equal, then jump to the return address or else call "stack_check_fail" function.
Nothing in the function is supposed to change the stack cookie. If it is changed this means that there is a buffer overflow. Stack check fail would print out "stack smashing detected" and will exit the program
Stack canaries can still be avaded and attacks conducted by:
Stack Canary leaking
Stack canary bruteforcing - Guessing bytes of the canary one by one. Once the offset is known, we can start adding a single byte (00 to ff) and see which byte doesn't cause crash. THe byte that doesn't is the correct one. We can extend this for all bytes until the correct 64 bit number is known.
Stack canaries always start with a null byte. Because in C, strings are terminated by null bytes. so if an attacker tries to read canary, C would stop it right before it accesses the canary since null byte would be encountered. However, some C functions would still allow reading of this canary even with a null byte in place.
Now when we step to next intruction where fs is being assigned to rax, we can see the canary
See how it ends with 00? In little endian, when a program would read it, it would start backwards, so from 00 and the reading function would be terminated upon encountering the canary.
Last updated