mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-22 11:03:24 +00:00
108 lines
6.7 KiB
Markdown
108 lines
6.7 KiB
Markdown
# Estouro de Pilha
|
|
|
|
<details>
|
|
|
|
<summary><strong>Aprenda hacking AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Outras formas de apoiar o HackTricks:
|
|
|
|
* Se você deseja ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
|
* Adquira o [**swag oficial PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* **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 seus truques de hacking enviando PRs para os** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
|
|
|
</details>
|
|
|
|
## O que é um Estouro de Pilha
|
|
|
|
Um **estouro de pilha** é uma vulnerabilidade que ocorre quando um programa escreve mais dados na pilha do que é alocado para armazenar. Esses dados em excesso irão **sobrescrever o espaço de memória adjacente**, levando à corrupção de dados válidos, interrupção do fluxo de controle e potencialmente à execução de código malicioso. Esse problema frequentemente surge devido ao uso de funções inseguras que não realizam verificação de limites na entrada.
|
|
|
|
O principal problema dessa sobrescrita é que o **ponteiro de instrução salvo (EIP/RIP)** e o **ponteiro de base salvo (EBP/RBP)** para retornar à função anterior são **armazenados na pilha**. Portanto, um atacante poderá sobrescrevê-los e **controlar o fluxo de execução do programa**.
|
|
|
|
A vulnerabilidade geralmente surge porque uma função **copia mais bytes para dentro da pilha do que a quantidade alocada para ela**, podendo assim sobrescrever outras partes da pilha.
|
|
|
|
Algumas funções comuns vulneráveis a isso são: **`strcpy`, `strcat`, `sprintf`, `gets`**... Além disso, funções como **`fgets`**, **`read` & `memcpy`** que recebem um **argumento de comprimento**, podem ser usadas de forma vulnerável se o comprimento especificado for maior do que o alocado.
|
|
|
|
Por exemplo, as seguintes funções poderiam ser vulneráveis:
|
|
```c
|
|
void vulnerable() {
|
|
char buffer[128];
|
|
printf("Enter some text: ");
|
|
gets(buffer); // This is where the vulnerability lies
|
|
printf("You entered: %s\n", buffer);
|
|
}
|
|
```
|
|
### Encontrando os deslocamentos de Estouro de Pilha
|
|
|
|
A maneira mais comum de encontrar estouros de pilha é fornecer uma entrada muito grande de `A`s (por exemplo, `python3 -c 'print("A"*1000)'`) e esperar um `Segmentation Fault` indicando que o **endereço `0x41414141` foi tentado ser acessado**.
|
|
|
|
Além disso, uma vez que você descobrir que há uma vulnerabilidade de Estouro de Pilha, será necessário encontrar o deslocamento até ser possível **sobrescrever o endereço de retorno**, para isso geralmente é usado uma **sequência de De Bruijn**. Que para um dado alfabeto de tamanho _k_ e subsequências de comprimento _n_ é uma **sequência cíclica na qual cada subsequência possível de comprimento _n_** aparece exatamente uma vez como uma subsequência contígua.
|
|
|
|
Dessa forma, em vez de precisar descobrir manualmente qual deslocamento é necessário para controlar o EIP, é possível usar uma dessas sequências como preenchimento e depois encontrar o deslocamento dos bytes que acabaram sobrescrevendo-o.
|
|
|
|
É possível usar o **pwntools** para isso:
|
|
```python
|
|
from pwn import *
|
|
|
|
# Generate a De Bruijn sequence of length 1000 with an alphabet size of 256 (byte values)
|
|
pattern = cyclic(1000)
|
|
|
|
# This is an example value that you'd have found in the EIP/IP register upon crash
|
|
eip_value = p32(0x6161616c)
|
|
offset = cyclic_find(eip_value) # Finds the offset of the sequence in the De Bruijn pattern
|
|
print(f"The offset is: {offset}")
|
|
```
|
|
ou **GEF**:
|
|
```bash
|
|
#Patterns
|
|
pattern create 200 #Generate length 200 pattern
|
|
pattern search "avaaawaa" #Search for the offset of that substring
|
|
pattern search $rsp #Search the offset given the content of $rsp
|
|
```
|
|
## Explorando Estouros de Pilha
|
|
|
|
Durante um estouro (supondo que o tamanho do estouro seja grande o suficiente), você será capaz de **sobrescrever** valores de variáveis locais dentro da pilha até atingir o **EBP/RBP e EIP/RIP salvos (ou até mais)**.\
|
|
A maneira mais comum de abusar desse tipo de vulnerabilidade é **modificando o endereço de retorno** para que, quando a função terminar, o **fluxo de controle seja redirecionado para onde o usuário especificou** nesse ponteiro.
|
|
|
|
No entanto, em outros cenários, talvez apenas **sobrescrever alguns valores de variáveis na pilha** seja suficiente para a exploração (como em desafios CTF fáceis).
|
|
|
|
### Ret2win
|
|
|
|
Nesse tipo de desafios CTF, há uma **função** **dentro** do binário que **nunca é chamada** e que **você precisa chamar para vencer**. Para esses desafios, você só precisa encontrar o **deslocamento para sobrescrever o endereço de retorno** e **encontrar o endereço da função** a ser chamada (geralmente [**ASLR**](../common-binary-protections-and-bypasses/aslr/) estaria desativado) para que, quando a função vulnerável retornar, a função oculta será chamada:
|
|
|
|
{% content-ref url="ret2win/" %}
|
|
[ret2win](ret2win/)
|
|
{% endcontent-ref %}
|
|
|
|
### Shellcode na Pilha
|
|
|
|
Nesse cenário, o atacante poderia colocar um shellcode na pilha e abusar do EIP/RIP controlado para pular para o shellcode e executar código arbitrário:
|
|
|
|
{% content-ref url="stack-shellcode/" %}
|
|
[stack-shellcode](stack-shellcode/)
|
|
{% endcontent-ref %}
|
|
|
|
### Técnicas ROP & Ret2...
|
|
|
|
Essa técnica é o framework fundamental para contornar a principal proteção da técnica anterior: **Pilha não executável (NX)**. E permite realizar várias outras técnicas (ret2lib, ret2syscall...) que acabarão executando comandos arbitrários abusando de instruções existentes no binário:
|
|
|
|
{% content-ref url="../rop-return-oriented-programing/" %}
|
|
[rop-return-oriented-programing](../rop-return-oriented-programing/)
|
|
{% endcontent-ref %}
|
|
|
|
## Estouros de Heap
|
|
|
|
Um estouro nem sempre ocorrerá na pilha, também pode ocorrer no **heap**, por exemplo:
|
|
|
|
{% content-ref url="../heap/heap-overflow.md" %}
|
|
[heap-overflow.md](../heap/heap-overflow.md)
|
|
{% endcontent-ref %}
|
|
|
|
## Tipos de proteções
|
|
|
|
Existem várias proteções que tentam evitar a exploração de vulnerabilidades, verifique-as em:
|
|
|
|
{% content-ref url="../common-binary-protections-and-bypasses/" %}
|
|
[common-binary-protections-and-bypasses](../common-binary-protections-and-bypasses/)
|
|
{% endcontent-ref %}
|