Stack Canaries - HackTricks

# Stack Canaries

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.

## StackGuard and StackShield

StackGuard inserts a special value known as a canary before the EIP (Extended Instruction Pointer), specifically `0x000aff0d` (representing null, newline, EOF, carriage return) to protect against buffer overflows. However, functions like `recv()`, `memcpy()`, `read()`, and `bcopy()` remain vulnerable, and it does not protect the EBP (Base Pointer).

StackShield takes a more sophisticated approach than StackGuard by maintaining a Global Return Stack, which stores all return addresses (EIPs). This setup ensures that any overflow does not cause harm, as it allows for a comparison between stored and actual return addresses to detect overflow occurrences. Additionally, StackShield can check the return address against a boundary value to detect if the EIP points outside the expected data space. However, this protection can be circumvented through techniques like Return-to-libc, ROP (Return-Oriented Programming), or ret2ret, indicating that StackShield also does not protect local variables.

## Stack Smash Protector (ProPolice) `-fstack-protector`:

This mechanism places a canary before the EBP, and reorganizes local variables to position buffers at higher memory addresses, preventing them from overwriting other variables. It also securely copies arguments passed on the stack above local variables and uses these copies as arguments. However, it does not protect arrays with fewer than 8 elements or buffers within a user's structure.

The canary is a random number derived from `/dev/urandom` or a default value of `0xff0a0000`. It is stored in TLS (Thread Local Storage), allowing shared memory spaces across threads to have thread-specific global or static variables. These variables are initially copied from the parent process, and child processes can alter their data without affecting the parent or siblings. Nevertheless, if a `fork()` is used without creating a new canary, all processes (parent and children) share the same canary, making it vulnerable. On the i386 architecture, the canary is stored at `gs:0x14`, and on x86_64, at `fs:0x28`.

This local protection identifies functions with buffers vulnerable to attacks and injects code at the start of these functions to place the canary, and at the end to verify its integrity.

When a web server uses `fork()`, it enables a brute-force attack to guess the canary byte by byte. However, using `execve()` after `fork()` overwrites the memory space, negating the attack. `vfork()` allows the child process to execute without duplication until it attempts to write, at which point a duplicate is created, offering a different approach to process creation and memory handling.

### Lengths

In `x64` binaries, the canary cookie is an `0x8` byte qword. The first seven bytes are random and the last byte is a null byte.

In `x86` binaries, the canary cookie is a `0x4` byte dword. The first three bytes are random and the last byte is a null byte.

> [!CAUTION] The least significant byte of both canaries is a null byte because it'll be the first in the stack coming from lower addresses and therefore functions that read strings will stop before reading it.

## Bypasses

Leaking the canary and then overwriting it (e.g. buffer overflow) with its own value.

- If the canary is forked in child processes it might be possible to brute-force it one byte at a time:

BF Forked & Threaded Stack Canaries

- If there is some interesting leak or arbitrary read vulnerability in the binary it might be possible to leak it:

Print Stack Canary

- Overwriting stack stored pointers

The stack vulnerable to a stack overflow might contain addresses to strings or functions that can be overwritten in order to exploit the vulnerability without needing to reach the stack canary. Check:

Pointer Redirecting

- Modifying both master and thread canary

A buffer overflow in a threaded function protected with canary can be used to modify the master canary of the thread. As a result, the mitigation is useless because the check is used with two canaries that are the same (although modified).

Moreover, a buffer overflow in a threaded function protected with canary could be used to modify the master canary stored in the TLS. This is because, it might be possible to reach the memory position where the TLS is stored (and therefore, the canary) via a bof in the stack of a thread.
As a result, the mitigation is useless because the check is used with two canaries that are the same (although modified).
This attack is performed in the writeup: http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads

Check also the presentation of https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015 which mentions that usually the TLS is stored by `mmap` and when a stack of thread is created it's also generated by `mmap` according to this, which might allow the overflow as shown in the previous writeup.

- Modify the GOT entry of `__stack_chk_fail`

If the binary has Partial RELRO, then you can use an arbitrary write to modify the GOT entry of `__stack_chk_fail` to be a dummy function that does not block the program if the canary gets modified.

This attack is performed in the writeup: https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/

## References

- https://guyinatuxedo.github.io/7.1-mitigation_canary/index.html
- http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads
- https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.