hacktricks/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/README.md

102 lines
9 KiB
Markdown

# Stack Canaries
{% hint style="success" %}
Aprenda e pratique Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Aprenda e pratique Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Suporte ao HackTricks</summary>
* Verifique os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe truques de hacking enviando PRs para os repositórios** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
{% endhint %}
## **StackGuard e StackShield**
**StackGuard** insere um valor especial conhecido como **canary** antes do **EIP (Extended Instruction Pointer)**, especificamente `0x000aff0d` (representando nulo, nova linha, EOF, retorno de carro) para proteger contra estouros de buffer. No entanto, funções como `recv()`, `memcpy()`, `read()` e `bcopy()` permanecem vulneráveis, e não protege o **EBP (Base Pointer)**.
**StackShield** adota uma abordagem mais sofisticada do que o StackGuard, mantendo uma **Global Return Stack**, que armazena todos os endereços de retorno (**EIPs**). Essa configuração garante que qualquer estouro não cause danos, pois permite a comparação entre os endereços de retorno armazenados e os reais para detectar ocorrências de estouro. Além disso, o StackShield pode verificar o endereço de retorno em relação a um valor de limite para detectar se o **EIP** aponta para fora do espaço de dados esperado. No entanto, essa proteção pode ser contornada por técnicas como Return-to-libc, ROP (Return-Oriented Programming) ou ret2ret, indicando que o StackShield também não protege variáveis locais.
## **Protetor de Stack Smash (ProPolice) `-fstack-protector`:**
Esse mecanismo coloca um **canary** antes do **EBP** e reorganiza as variáveis locais para posicionar buffers em endereços de memória mais altos, impedindo que eles sobrescrevam outras variáveis. Ele também copia com segurança os argumentos passados na pilha acima das variáveis locais e usa essas cópias como argumentos. No entanto, não protege arrays com menos de 8 elementos ou buffers dentro de uma estrutura do usuário.
O **canary** é um número aleatório derivado de `/dev/urandom` ou um valor padrão de `0xff0a0000`. Ele é armazenado no **TLS (Thread Local Storage)**, permitindo que espaços de memória compartilhados entre threads tenham variáveis globais ou estáticas específicas da thread. Essas variáveis são inicialmente copiadas do processo pai, e os processos filhos podem alterar seus dados sem afetar o pai ou irmãos. No entanto, se um **`fork()`** é usado sem criar um novo canary, todos os processos (pai e filhos) compartilham o mesmo canary, tornando-o vulnerável. Na arquitetura **i386**, o canary é armazenado em `gs:0x14`, e no **x86\_64**, em `fs:0x28`.
Essa proteção local identifica funções com buffers vulneráveis a ataques e injeta código no início dessas funções para colocar o canary e no final para verificar sua integridade.
Quando um servidor web usa `fork()`, ele permite um ataque de força bruta para adivinhar o byte do canary por byte. No entanto, usar `execve()` após `fork()` sobrescreve o espaço de memória, anulando o ataque. `vfork()` permite que o processo filho execute sem duplicação até tentar escrever, momento em que uma duplicata é criada, oferecendo uma abordagem diferente para a criação de processos e manipulação de memória.
### Comprimentos
Em binários `x64`, o cookie do canary é um qword de **`0x8`** bytes. Os **sete primeiros bytes são aleatórios** e o último byte é um **byte nulo**.
Em binários `x86`, o cookie do canary é um dword de **`0x4`** bytes. Os **três primeiros bytes são aleatórios** e o último byte é um **byte nulo**.
{% hint style="danger" %}
O byte menos significativo de ambos os canaries é um byte nulo porque será o primeiro na pilha vindo de endereços mais baixos e, portanto, **funções que leem strings irão parar antes de lê-lo**.
{% endhint %}
## Bypasses
**Vazando o canary** e então sobrescrevendo-o (por exemplo, estouro de buffer) com seu próprio valor.
* Se o **canary é bifurcado em processos filhos**, pode ser possível **forçá-lo por tentativa e erro** um byte de cada vez:
{% content-ref url="bf-forked-stack-canaries.md" %}
[bf-forked-stack-canaries.md](bf-forked-stack-canaries.md)
{% endcontent-ref %}
* Se houver alguma **vulnerabilidade de vazamento ou leitura arbitrária interessante** no binário, pode ser possível vazá-lo:
{% content-ref url="print-stack-canary.md" %}
[print-stack-canary.md](print-stack-canary.md)
{% endcontent-ref %}
* **Sobrescrevendo ponteiros armazenados na pilha**
A pilha vulnerável a um estouro de pilha pode **conter endereços de strings ou funções que podem ser sobrescritos** para explorar a vulnerabilidade sem precisar alcançar o canary da pilha. Verifique:
{% content-ref url="../../stack-overflow/pointer-redirecting.md" %}
[pointer-redirecting.md](../../stack-overflow/pointer-redirecting.md)
{% endcontent-ref %}
* **Modificando tanto o canary mestre quanto o da thread**
Um **estouro de buffer em uma função com thread** protegida com canary pode ser usado para **modificar o canary mestre da thread**. Como resultado, a mitigação é inútil porque a verificação é feita com dois canaries que são iguais (embora modificados).
Além disso, um **estouro de buffer em uma função com thread** protegida com canary poderia ser usada para **modificar o canary mestre armazenado no TLS**. Isso ocorre porque pode ser possível alcançar a posição de memória onde o TLS é armazenado (e, portanto, o canary) por meio de um **bof na pilha** de uma thread.\
Como resultado, a mitigação é inútil porque a verificação é feita com dois canaries que são iguais (embora modificados).\
Esse ataque é realizado no artigo: [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads)
Verifique também a apresentação de [https://www.slideshare.net/codeblue\_jp/master-canary-forging-by-yuki-koike-code-blue-2015](https://www.slideshare.net/codeblue\_jp/master-canary-forging-by-yuki-koike-code-blue-2015) que menciona que geralmente o **TLS** é armazenado por **`mmap`** e quando uma **pilha** de **thread** é criada, também é gerada por `mmap` de acordo com isso, o que pode permitir o estouro conforme mostrado no artigo anterior.
* **Modificar a entrada GOT de `__stack_chk_fail`**
Se o binário tiver Partial RELRO, então você pode usar uma escrita arbitrária para modificar a **entrada GOT de `__stack_chk_fail`** para ser uma função fictícia que não bloqueia o programa se o canary for modificado.
Esse ataque é realizado no artigo: [https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/](https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/)
## Referências
* [https://guyinatuxedo.github.io/7.1-mitigation\_canary/index.html](https://guyinatuxedo.github.io/7.1-mitigation\_canary/index.html)
* [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads)
* [https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/](https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/)
{% hint style="success" %}
Aprenda e pratique Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Treinamento AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Aprenda e pratique Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Treinamento GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Suporte ao HackTricks</summary>
* Verifique os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe truques de hacking enviando PRs para os repositórios** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
{% endhint %}