Comment décoder une commande PowerShell encodée
- Copiez la ligne de commande complète depuis l’alerte, l’événement de création de processus ou la console EDR, et collez-la dans Ligne de commande ou Base64. Les guillemets autour du Base64 ne gênent pas.
- Le décodeur trouve l’argument
-EncodedCommandsous n’importe quelle abréviation (-e,-ec,-encet ainsi de suite, avec-ou/) et le décode. - Le message d’état indique le jeu de caractères utilisé : UTF-16LE, comme l’attend PowerShell, ou UTF-8 quand les octets ne ressemblent pas à de l’UTF-16.
- Lisez le Script décodé. S’il contient des littéraux
[Convert]::FromBase64String('…'), ils sont listés en dessous avec leur type détecté et leur taille. Les payloads texte s’ouvrent dans le panneau de sortie, les payloads compressés (gzip, zlib ou deflate brut, comme avecGzipStreametDeflateStream) reçoivent un bouton de décompression, et les autres payloads binaires peuvent être enregistrés dans un fichier.
Un exemple inoffensif :
powershell.exe -NoP -NonI -W Hidden -Enc VwByAGkAdABlAC0ATwB1AHQAcAB1AHQAIAAnAGgAZQBsAGwAbwAnAA==
se décode en Write-Output 'hello'. Le même texte en Base64 UTF-8 donnerait V3JpdGUtT3V0cHV0ICdoZWxsbyc=, que PowerShell rejetterait ou lirait de travers.
Reconnaître les commandes encodées dans les logs
En raison de l’UTF-16LE, le début d’un script encodé a une forme Base64 reconnaissable. Les règles de détection s’appuient sur ces formes :
| Le Base64 commence par | Le script commence par |
|---|---|
JAB | $ (une affectation de variable, par ex. JABzAD0A correspond à $s=) |
SQBFAFgA | IEX |
aQBlAHgA | iex |
SQBuAHYAbwBrAGUALQBFAHgAcAByAGUAcwBzAGkAbwBuAA | Invoke-Expression |
SQBuAHYAbwBrAGUALQBXAGUAYgBSAGUAcQB1AGUAcwB0AA | Invoke-WebRequest |
TgBlAHcALQBPAGIAagBlAGMAdAA | New-Object |
WwBDAG8AbgB2AGUAcgB0AF0AOgA6AEYAcgBvAG0AQgBhAHMAZQA2ADQAUwB0AHIAaQBuAGcA | [Convert]::FromBase64String |
Ces formes ne valent qu’au tout début. Plus loin dans le script, un même mot peut s’écrire de trois façons en Base64, selon son décalage en octets modulo 3 : c’est pourquoi chercher une seule écriture dans les logs fait manquer les deux autres.
Analyser une commande suspecte en toute sécurité
Les commandes encodées sont un moyen courant de cacher un script à un examen rapide de la liste des processus. Quand l’une d’elles apparaît dans une alerte :
- Décodez seulement. Cette page convertit du texte et n’effectue aucune requête réseau hormis le comptage des pages vues de Cloudflare. Ne collez pas la commande dans une fenêtre PowerShell, et ne passez jamais la sortie décodée à
iex. - Lisez pour comprendre l’intention et relever les indicateurs. Notez les URL, domaines, adresses IP, chemins de fichiers, clés de registre et noms de tâches planifiées pour vos notes d’incident et vos listes de blocage.
- Cherchez d’autres couches. Les appels
FromBase64Stringimbriqués,IO.Compression.DeflateStreamouGzipStream, les-joinsur des codes de caractères et l’inversion de chaînes sont des enveloppes courantes. Décodez chaque couche de la même façon. - Traitez les binaires extraits comme des échantillons. Un payload enregistré depuis la liste des éléments imbriqués peut être un malware. Calculez son empreinte et ne l’analysez que dans un environnement isolé.
- Consultez les logs qui contiennent déjà le texte en clair. Avec le Script Block Logging activé, Windows enregistre le script décodé dans l’événement 4104 de
Microsoft-Windows-PowerShell/Operational. Les événements de création de processus (Security 4688 avec l’audit de ligne de commande, ou l’événement Sysmon 1) enregistrent la ligne de commande encodée elle-même.
Usages légitimes et onglet d’encodage
Les administrateurs utilisent -EncodedCommand pour éviter les problèmes de guillemets quand un script passe par cmd.exe, une tâche planifiée, un shell distant ou un outil de gestion de configuration. Encoder un script produit l’argument : saisissez le script, choisissez le préfixe Commande (powershell -NoProfile -EncodedCommand, pwsh -NoProfile -EncodedCommand, powershell -enc ou Base64 seul) et copiez. Un avertissement apparaît quand le résultat dépasse la limite de 8 191 caractères par ligne de commande de cmd.exe.
Décoder en Python et en PowerShell
import base64
script = base64.b64decode(b64).decode("utf-16-le")
$script = [Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($b64))
Les deux renvoient seulement du texte. Plus d’informations sur l’encodage sur la page Base64 en PowerShell et dans le convertisseur UTF-16 en Base64.
Problèmes courants
- La sortie ressemble à des caractères chinois : du Base64 UTF-8 décodé comme de l’UTF-16. L’outil se rabat sur l’UTF-8 quand le motif des octets ne correspond pas à de l’UTF-16, et la ligne d’état indique le jeu de caractères utilisé.
- Base64 non valide : la commande a été coupée par une limite de champ de log ou répartie sur plusieurs lignes. Réunissez les morceaux et supprimez tout ce qui suit le Base64 sans en faire partie.
- La ligne de commande ne se décode pas du tout : le Base64 se trouve peut-être dans une chaîne
-Command "…FromBase64String('…')…"au lieu de suivre-EncodedCommand. Collez seulement la chaîne Base64 ; si ce n’est pas du texte UTF-16, le décodeur Base64 ou Base64 en fichier montre de quoi il s’agit.
FAQ
Que fait powershell -enc ?
-enc est une forme abrégée de -EncodedCommand. PowerShell décode l’argument Base64 comme du texte UTF-16LE et l’exécute comme un script. Il accepte aussi d’autres abréviations comme -e et -ec.
Est-il sûr de décoder ici une commande PowerShell malveillante ?
Le décodage est une conversion de texte : rien n’est exécuté, et la Content Security Policy de cette page bloque toutes les requêtes réseau hormis le comptage des pages vues de Cloudflare. N’exécutez jamais le script décodé pour voir ce qu’il fait, et ne manipulez les payloads binaires enregistrés que dans un environnement d’analyse isolé.
Pourquoi un caractère sur deux est-il un A dans le Base64 ?
PowerShell attend de l’UTF-16LE, où chaque caractère ASCII est suivi d’un octet nul. Ces octets nuls produisent le motif répétitif de A, comme dans VwByAGkAdABlAC0A pour Write-.
Comment décoder -EncodedCommand sans l'exécuter dans PowerShell ?
Utilisez [Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($b64)), qui renvoie seulement le texte. Ne passez pas le résultat à Invoke-Expression ni à iex.