
Débordement de tampon basé sur la pile dans R 3.4.4. Exploitation complète sur x86, mais seulement contrôle RIP avec analyse de gadgets sur x64 en raison des contraintes du programme. La même vulnérabilité sur deux architectures, menant à des chemins d'exploitation différents.
Débordement de tampon basé sur la pile dans R 3.4.4. Exploitation complète sur x86, mais seulement contrôle de RIP avec analyse de gadgets sur x64 en raison des contraintes du programme. La même vulnérabilité sur deux architectures, menant à des chemins d'exploitation différents.
Ce dépôt fait partie du matériel que j'utilise lorsque j'enseigne l'exploitation de corruptions mémoire (en plus de mon travail régulier, j'enseigne également dans différents cours de cybersécurité où j'aide à former la prochaine génération de rétro-ingénieurs).
CVE-2019-25485 est le cas que j'utilise lorsque je souhaite que les étudiants travaillent sur la même vulnérabilité sur deux architectures différentes et voient de première main ce qui change entre elles. R 3.4.4 est disponible en versions x86 et x64, et le même débordement existe dans les deux, le même champ d'interface graphique, le même gestionnaire d'entrée, le même crash. Les deux sont documentés et exploités ici comme exercices distincts :
R 3.4.4 est une application de calcul statistique, pas un service réseau ou un navigateur. Le débordement est déclenché via un champ d'interface graphique de bureau, ce qui signifie que la surface d'attaque est complètement différente de tous les autres cas que j'enseigne. Ce qui rend ce cas utile pour l'enseignement :
R est un environnement de calcul statistique et de graphisme disponible pour Windows, macOS et Linux. La vulnérabilité se trouve dans la boîte de dialogue des préférences de l'interface graphique, plus précisément le champ Langue pour les menus et messages, qui copie l'entrée utilisateur dans un tampon de pile de taille fixe sans valider sa longueur.
Détails techniques clés :
R 3.4.4 traite le champ Langue pour les menus et messages en copiant la chaîne fournie dans un tampon de pile de taille fixe sans vérifier sa longueur. Une version simplifiée de la logique vulnérable ressemble à ceci :
char language_buffer[256];
strcpy(language_buffer, user_input);
Envoyer une chaîne suffisamment longue provoque la copie au-delà de la fin du tampon, corrompant la pile jusqu'à ce que l'adresse de retour sauvegardée soit écrasée. Lorsque la fonction retourne, le CPU charge la valeur contrôlée par l'attaquant depuis la pile dans RIP et tente d'y sauter.
Sur x64, Windows applique la validation des adresses canoniques avant tout saut. Une valeur non canonique comme 0x4141414141414141 déclenche immédiatement une violation d'accès avant que RIP ne soit chargé, ce qui signifie que le crash semble différent de celui sur x86, pas de RIP = 4141414141414141 propre. Le décalage doit être trouvé en lisant le motif cyclique depuis la pile après le crash plutôt que directement depuis RIP.
Le crash peut être reproduit en collant une longue chaîne dans le champ de langue. Aucune authentification n'est requise. Exemple utilisant Python pour générer la charge utile :
import struct
payload = b'A' * 400
with open('payload.txt', 'wb') as f:
f.write(payload)
Ouvrir R 3.4.4 x64
Édition -> Préférences de l'interface graphique
Coller le contenu de payload.txt dans Langue pour les menus et messages
Cliquer sur OK
Le but de ce dépôt n'est pas seulement de démontrer le crash, mais de parcourir le processus d'exploitation complet sur les deux architectures, en documentant ce qui fonctionne sur x86, ce qui casse sur x64, et plus important encore, pourquoi.
Pour garder le README principal propre, les notes d'exploitation détaillées, les scripts et les étapes du débogueur sont placés dans le dossier Vulnerability 📂 de ce dépôt, organisés en sous-dossiers séparés x86 et x64.
Vous y trouverez le flux de travail complet pour les deux architectures :
x86 - Exploitation complète :
x64 - Contrôle de RIP et analyse d'exploitation :