Aller au contenu

Exécution

Journaux et historique PowerShell

Forensique PowerShell : journaux 4103/4104, événements 400/403/800, historique PSReadLine ConsoleHost_history.txt, transcriptions et clés de stratégie.

Emplacement
C:\Windows\System32\winevt\Logs\Microsoft-Windows-PowerShell%4Operational.evtx
Prouve
Quel code PowerShell a tourné, sous quel compte et quand ; commandes tapées par utilisateur
Horodatages
TimeCreated en FILETIME, UTC ; lignes PSReadLine non datées ($SI du fichier seulement) ; noms et en-têtes de transcripts en heure locale, sans fuseau
Rétention
Journalisation détaillée désactivée par défaut ; EVTX circulaire à taille max (quelques jours sur hôte chargé) ; PSReadLine garde les 4 096 dernières commandes
Accès
Administrateur pour les EVTX (verrouillés à chaud, export via wevtutil epl) ; l'historique PSReadLine est un fichier texte dans chaque profil
Preuve de
Exécution
Type
Journal d'événements
Windows
Vista / 78 / 8.11011
Cible KAPE
EventLogsPowerShellConsolePowerShellTranscripts
Velociraptor
Windows.Triage.Targets:EventLogsPowerShellConsolePowerShellTranscripts

Présentation

PowerShell est le LOLBin préféré des attaquants : il télécharge des charges, exécute du code en mémoire et pilote les mouvements latéraux sans déposer le moindre binaire. Windows en conserve plusieurs traces indépendantes. Deux journaux d'événements enregistrent le moteur et le code lui-même, le module PSReadLine sauvegarde ce que les utilisateurs ont tapé dans la console, et la transcription, optionnelle, écrit des sessions entières dans des fichiers texte. Chaque source a ses propres réglages par défaut : savoir ce qui est journalisé d'origine compte autant que savoir où chercher.

Emplacement

SourceEmplacementDisponibilité
Journal Operational (Windows PowerShell 5.x)Microsoft-Windows-PowerShell/Operational → C:\Windows\System32\winevt\Logs\Microsoft-Windows-PowerShell%4Operational.evtxLa journalisation des blocs de script exige PowerShell 5 (natif sous Windows 10/11, WMF 5.1 sous 7/8.1)
Journal classiqueWindows PowerShell → C:\Windows\System32\winevt\Logs\Windows PowerShell.evtxToutes versions
Journal PowerShell 7PowerShellCore/Operational → PowerShellCore%4Operational.evtxSeulement si PowerShell 7 est installé et son fournisseur d'événements enregistré
Historique PSReadLineC:\Users\<utilisateur>\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txtPowerShell 5.1 et suivants (PSReadLine est livré avec Windows 10 et ultérieur)
TranscriptionsPowerShell_transcript.<ORDINATEUR>.<aléatoire>.<yyyyMMddHHmmss>.txt, par défaut dans le dossier Documents de l'utilisateur, ou dans l'OutputDirectory défini par stratégie (sous-dossiers quotidiens yyyyMMdd)Uniquement si la transcription est activée
Stratégie de journalisationHKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ (ScriptBlockLogging, ModuleLogging, Transcription) ; PowerShell 7 : HKLM\SOFTWARE\Policies\Microsoft\PowerShellCore\Ruche SOFTWARE (les stratégies de Configuration utilisateur vont dans NTUSER.DAT)

Le nom du fichier d'historique dépend de l'hôte : ConsoleHost_history.txt pour la console, Visual Studio Code Host_history.txt pour l'extension VS Code. Les comptes comme SYSTEM ont le leur sous C:\Windows\System32\config\systemprofile\AppData\Roaming\....

Ce que l'artefact prouve

  • Code exécuté : l'événement 4104 conserve le texte de chaque bloc de script compilé par PowerShell, y compris le contenu décodé d'un -EncodedCommand et le code passé à Invoke-Expression, avec le compte qui l'a lancé.
  • Démarrage du moteur et ligne de commande : 400 (état du moteur None → Available) et 403 (Available → Stopped) dans Windows PowerShell.evtx, avec un champ HostApplication qui contient la ligne de commande complète.
  • Commandes et paramètres : 4103 (journalisation des modules) dans le journal Operational et 800 (détails d'exécution du pipeline) dans le journal classique enregistrent les cmdlets et leurs paramètres.
  • Ce qu'un utilisateur a tapé : ConsoleHost_history.txt liste les commandes saisies dans la console, y compris pour des sessions dont les journaux ont été effacés.
  • L'artefact ne prouve pas la réussite : un bloc journalisé a pu échouer. PSReadLine ne capture ni les scripts lancés avec -File, ni les lancements non interactifs en -Command, ni les sessions à distance.

Champs clés

Événement / fichierChamps utilesRemarques
4104 OperationalMessageNumber, MessageTotal, ScriptBlockText, ScriptBlockId, PathLes gros scripts sont découpés en plusieurs événements partageant le même ScriptBlockId
4103 OperationalContextInfo (hôte, utilisateur, nom de commande), Payload (paramètres liés)Seulement si la journalisation des modules est active
4105 / 4106 OperationalScriptBlockId, RunspaceIdDébut et fin d'invocation ; seulement avec la journalisation des invocations
400 / 403 classiqueHostApplication, EngineVersion, HostNameUn EngineVersion 2.0 évoque un retour à la v2 pour échapper à la journalisation
800 classiqueUserId, HostApplication, détail des commandesÉcrit quand la journalisation des modules est active
ConsoleHost_history.txtUne commande par ligne (les commandes multilignes sont conservées)Texte brut, sans horodatage
TranscriptionEn-tête (utilisateur, machine, application hôte, heure de début), puis entrées et sortiesEn-tête par commande avec EnableInvocationHeader

Horodatages

HorodatagePositionné quandFormatPièges
TimeCreated de l'événementCompilation d'un bloc, démarrage/arrêt du moteur, exécution d'un pipelineFILETIME, UTCL'Observateur d'événements affiche l'heure locale : convertissez avant de corréler (UTC et heure locale)
Modification $SI de l'historiqueAjout de la dernière commandeNTFS, UTCNe date que la dernière ligne ; les commandes ne sont pas datées individuellement
Création $SI de l'historiquePremière commande sauvegardée pour cet hôteNTFS, UTCRéinitialisée si le fichier a été supprimé puis recréé
Nom et en-tête de la transcriptionDébut de sessionHeure locale, yyyyMMddHHmmssAucune indication de fuseau horaire

Rétention et effacement

  • Rien de détaillé n'est actif par défaut. La journalisation des blocs de script, des modules et des invocations doit être activée par stratégie (EnableScriptBlockLogging, EnableModuleLogging avec une liste ModuleNames, EnableScriptBlockInvocationLogging). Sans elles, PowerShell écrit malgré tout un 4104 de niveau Avertissement pour les blocs dont le contenu lui paraît suspect.
  • Les journaux tournent quand ils atteignent leur taille maximale ; sur un hôte actif avec la journalisation des blocs, le journal Operational peut ne couvrir que quelques jours.
  • PSReadLine garde par défaut les 4 096 dernières commandes (MaximumHistoryCount), sauvegarde après chaque commande et écarte les lignes contenant des chaînes sensibles comme password, asplaintext, token, apikey ou secret.
  • Anti-forensique : Set-PSReadLineOption -HistorySaveStyle SaveNothing, suppression ou modification du fichier d'historique, wevtutil cl, lancement de powershell -Version 2, suppression des clés de stratégie. L'effacement d'un journal laisse l'événement 104 dans System (1102 pour Security) ; voir journaux d'événements Windows.

Collecte

  • Cibles KAPE : EventLogs (tous les .evtx), PowerShellConsole (historique PSReadLine et fichiers d'enregistrement automatique de l'ISE), PowerShellTranscripts (dossiers de transcription par défaut et courants).
  • Velociraptor (Windows.Triage.Targets) : EventLogs, PowerShellConsole, PowerShellTranscripts.
  • Commandes natives : les clés de stratégie se trouvent dans la ruche SOFTWARE (RegistryHivesSystem) ; exportez-les ou lisez-les à chaud.
wevtutil epl Microsoft-Windows-PowerShell/Operational E:\case\PS-Operational.evtx
wevtutil epl "Windows PowerShell" E:\case\WindowsPowerShell.evtx
Get-ChildItem C:\Users\*\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\*_history.txt -Force |
  Copy-Item -Destination E:\case\PSReadLine\ -PassThru
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell /s

Une transcription écrite dans un OutputDirectory personnalisé n'est pas couverte par les cibles par défaut : lisez d'abord la clé de stratégie Transcription, puis collectez ce dossier à part.

Outils d'analyse

  • EvtxECmd (Eric Zimmerman) : fournit des maps pour 4103, 4104, 400, 403, 600 et 800, ainsi que pour 4104 dans PowerShellCore/Operational.
  • Chainsaw et Hayabusa (open source) : chasse fondée sur Sigma dans les 4104 et le journal classique.
  • Velociraptor : Windows.EventLogs.PowershellScriptblock (4104, blocs de niveau Avertissement par défaut), Windows.EventLogs.PowershellModule (4103) et Windows.System.Powershell.PSReadline.
  • Get-WinEvent : filtrez par identifiant et recollez les segments ScriptBlockText par ScriptBlockId pour reconstituer les longs scripts.
  • N'importe quel éditeur de texte pour ConsoleHost_history.txt et les transcriptions.

Conseils d'investigation

  • Commencez par les 4104 de niveau Avertissement : ils existent même là où personne n'a activé la journalisation, et ils signalent précisément les blocs que PowerShell lui-même a jugés suspects.
  • Reconstituez les scripts découpés par ScriptBlockId avant de décoder : la charge est souvent un blob Base64 ou compressé dans un segment ultérieur.
  • Comparez le HostApplication du 400 avec les 4104 : un powershell.exe -nop -w hidden -enc ... lancé par wmiprvse.exe, mshta.exe ou un processus Office oriente vers WMI ou une macro.
  • Examinez le ConsoleHost_history.txt de chaque utilisateur, comptes de service et d'administration compris : un attaquant en session interactive tape souvent Invoke-WebRequest, Add-MpPreference -ExclusionPath ou des commandes de vol d'identifiants.
  • Corrélez les exécutions de powershell.exe dans le Prefetch avec les plages horaires des 4104, et cherchez des détections AMSI pour les mêmes scripts dans les journaux Microsoft Defender.
  • Vérifiez les clés de stratégie de journalisation et leur date de dernière écriture : une journalisation désactivée peu avant l'incident relève elle-même de l'anti-forensique.

Artefacts liés

Termes du glossaire

Guides

Tous les artefacts sur une page : aide-mémoire