.. | ||
ret2lib | ||
ebp2ret-ebp-chaining.md | ||
README.md | ||
ret2ret.md | ||
ret2shellcode.md | ||
ret2win.md | ||
rop-return-oriented-programing.md | ||
rop-syscall-execv.md | ||
stack-shellcode.md |
Estouro de Pilha
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras maneiras de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF Verifique os PLANOS DE ASSINATURA!
- Adquira o swag oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe seus truques de hacking enviando PRs para os HackTricks e HackTricks Cloud repositórios do github.
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 segurar. 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 os ponteiros EIP e EBP 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, sendo capaz de sobrescrever outras partes da pilha.
Algumas funções comuns vulneráveis a isso são: strcpy
, strcat
, sprintf
, gets
, fgets
...
Por exemplo, as seguintes funções poderiam ser vulneráveis:
void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
Encontrando Estouros 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 ponteiro EIP, 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 toda 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 está sobrescrevendo 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:
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:
#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 de pilha (supondo que o tamanho do estouro seja grande o suficiente), você poderá sobrescrever valores de outras variáveis dentro da pilha até atingir o EBP e EIP (ou até mais).
A maneira mais comum de abusar desse tipo de vulnerabilidade é modificando o ponteiro EIP 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 EIP e encontrar o endereço da função a ser chamada (geralmente ASLR estaria desativado) para que, quando a função vulnerável retornar, a função oculta será chamada:
{% content-ref url="ret2win.md" %} ret2win.md {% endcontent-ref %}
Shellcode na Pilha
Nesse cenário, o atacante poderia colocar um shellcode na pilha e abusar do EIP controlado para ir para o shellcode e executar o código do atacante:
{% content-ref url="stack-shellcode.md" %} stack-shellcode.md {% endcontent-ref %}
ROP
Essa técnica é o framework fundamental para contornar a principal proteção da técnica anterior: Pilha não executável. 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.md" %} rop-return-oriented-programing.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/" %} common-binary-protections {% endcontent-ref %}
Aprenda hacking na AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras maneiras de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF, verifique os PLANOS DE ASSINATURA!
- Adquira o swag oficial do PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe seus truques de hacking enviando PRs para os repositórios do HackTricks e HackTricks Cloud.