Ce qu'enregistrent les journaux PowerShell
PowerShell produit plusieurs traces indépendantes. Le Script Block Logging (événement 4104, dans le journal Microsoft-Windows-PowerShell/Operational) enregistre le code réellement exécuté — le texte du script désobfusqué, réparti sur plusieurs événements 4104 pour les blocs longs. La journalisation des modules (4103) enregistre le détail de l'exécution du pipeline. Le journal classique « Windows PowerShell » enregistre le cycle de vie du moteur et des fournisseurs (400/403/600) et, avec une stratégie, l'exécution du pipeline (800).
En dehors des journaux d'événements, PSReadLine conserve un historique en texte brut de tout ce qui est saisi dans une console interactive, et Start-Transcript (ou la stratégie de transcription) écrit la transcription complète d'une session dans un fichier texte. Ensemble, ils constituent l'une des sources les plus riches sur ce qu'un opérateur — ou un intrus — a fait sur un hôte Windows.
Emplacements de stockage
- C:\Windows\System32\winevt\Logs\Microsoft-Windows-PowerShell%4Operational.evtx — Script Block Logging (4104) et journalisation des modules (4103).
- C:\Windows\System32\winevt\Logs\Windows PowerShell.evtx — événements classiques moteur/fournisseur/pipeline (400/403/600/800).
- C:\Users\<user>\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt — historique des commandes interactives, par utilisateur.
- C:\Users\<user>\Documents\PowerShell_transcript.<host>.<random>.<timestamp>.txt — transcriptions, si elles sont activées.
Intérêt pour une investigation
- Le Script Block Logging capture le code tel que PowerShell l'a vu : un -EncodedCommand ou un one-liner obfusqué est enregistré sous sa forme développée — et cet outil décode en plus pour vous les couches encodées et compressées.
- La reconstitution des 4104 par ScriptBlockId et MessageNumber/MessageTotal recrée les longs scripts que Windows a découpés sur plusieurs événements, et signale toute partie manquante.
- L'historique PSReadLine et les transcriptions capturent une activité interactive qui peut ne jamais passer par un fichier de script, y compris les fautes de frappe et les commandes abandonnées.
- Les détections mettent en évidence les cradles de téléchargement, les contournements AMSI/ETW, l'altération de la journalisation et de Defender, le contournement de la stratégie d'exécution, les fenêtres masquées, les rétrogradations du moteur et les techniques d'obfuscation courantes — comme pistes à vérifier, pas comme verdicts.
Limites
- Le Script Block Logging est désactivé par défaut ; sans lui, vous ne verrez peut-être que les blocs de niveau Avertissement signalés d'office par Windows, ainsi que le journal classique et l'historique.
- L'historique PSReadLine n'a pas d'horodatage : son ordre est la seule chronologie, et il peut être bien plus ancien que les journaux.
- Les heures des transcriptions suivent l'horloge locale de l'hôte sans fuseau ; celles des journaux d'événements sont en UTC.
- Les journaux font l'objet d'une rotation et peuvent être effacés ; cet outil signale les commandes d'effacement mais ne peut pas récupérer les événements déjà supprimés.
Comment récupérer les fichiers
- Exportez les deux journaux d'événements PowerShell avec wevtutil epl (ou collectez tous les .evtx avec KAPE / Velociraptor), et copiez l'historique PSReadLine et les transcriptions de chaque utilisateur.
- Sur un hôte actif, le service EventLog garde les journaux ouverts : utilisez un export plutôt qu'une simple copie.
- Conservez l'arborescence Users\<name>\ afin que l'historique et les transcriptions soient attribués au bon compte.
FAQ
Mes fichiers sont-ils envoyés quelque part ?
Non. L'analyseur — y compris le lecteur .evtx — est écrit en Rust compilé en WebAssembly et s'exécute dans un Web Worker de votre navigateur. Il n'existe aucun point de terminaison d'envoi, et aucun contenu de script n'est jamais exécuté.
Décode-t-il -EncodedCommand et les scripts obfusqués ?
Oui. Le base64 de -EncodedCommand est décodé depuis l'UTF-16LE, et les couches suivantes — charges gzip/deflate, codes [char], concaténation de chaînes, opérateur de format -f et échappement par backticks — sont déroulées et affichées en texte inerte. Le script n'est jamais exécuté.
Comment reconstitue-t-il un bloc de script réparti sur plusieurs événements ?
Windows découpe un long bloc de script sur plusieurs événements 4104 partageant un même ScriptBlockId, chacun portant MessageNumber sur MessageTotal. L'analyseur regroupe par ScriptBlockId, trie par MessageNumber, concatène le texte et signale toute partie manquante.
Et si le Script Block Logging était désactivé ?
Vous verrez tout de même le journal Windows PowerShell classique (événements moteur et pipeline), l'historique PSReadLine et les éventuelles transcriptions. Windows journalise aussi au niveau Avertissement les blocs de script qu'il juge suspects, même lorsque la journalisation complète est désactivée, et ceux-ci sont également pris en compte.
Quels fichiers dois-je collecter ?
Microsoft-Windows-PowerShell%4Operational.evtx et Windows PowerShell.evtx depuis winevt\Logs, le ConsoleHost_history.txt de chaque utilisateur, et tous les PowerShell_transcript.*.txt. Le guide de collecte intégré fournit des exports en une seule commande.