Afin de tester un algorithme non supervisé de détection d’anomalie, il nous faut un ensemble de données présentant aussi bien des activités d’authentification inoffensives que malveillantes. Nous avons déjà accès à des données inoffensives, mais manquons d’évènements de type « attaque ».
La question que nous tentons ici de traiter est la suivante : pouvons-nous simuler un comportement malveillant en injectant, dans un ensemble de données inoffensives, des données dont nous savons qu’elles sont malveillantes ?
Dans cet article, nous nous concentrons sur les attaques par « essai-erreur » sur des mots de passe, bien que la méthode proposée fonctionne aussi pour d’autres types d’attaques.
Il existe deux principaux types d’attaques de type « essai-erreur » sur les mots de passe :
Les attaques par brute-force: tentatives de connexion à un compte donné par l’utilisation de plusieurs mots de passe saisis l’un après l’autre. Les mots de passe peuvent être aléatoires ou venir d’un dictionnaire de mots de passe couramment utilisés.
Les attaques par password spraying: tentatives de connexion à plusieurs comptes par utilisation d’un même mot de passe. Une fois qu’un mot de passe a été utilisé pour tester l’ensemble des comptes, ce procédé recommence avec le mot de passe suivant, et ainsi de suite. Cette méthode évite le verrouillage du compte qui intervient généralement lorsqu’un seul compte fait l’objet d’une attaque par force brute.
Par simplicité, nous considérons la modélisation d’une attaque par brute-force. Néanmoins, les méthodes qui suivent peuvent aussi être appliquées au password spraying, moyennant des modifications minimes.
Créer des données malveillantes et les insérer dans des données inoffensives réelles
Dans un précédent article, nous avons traité de la constitution d’un lab composé de plusieurs machines virtuelles (VM) appartenant à un même Active Directory (AD), permettant la génération d’attaques en environnement contrôlé, et la collecte des journaux d’authentification.
Dans le cas présent, le problème est inversé : nous disposons de données réelles et inoffensives, mais ne pouvons pas obtenir de données malveillantes provenant des mêmes postes de travail. Cela reviendrait en effet à attaquer de vraies machines, utilisées au quotidien par de vrais individus (or, trouver des individus acceptant de subir des attaques alors même qu’ils travaillent et consentant à être tenus pour légalement responsables n’est pas chose aisée).
Sur la base de ce que nous savons des évènements générés par des attaques créées avec des outils comme Hydra, Kerbrute, ou CrackMapExec, nous avons pu recréer ces évènements et les insérer dans des évènements bénins à notre disposition.
À quoi ressemblent les authentifications par brute-force ?
Windows regroupe nativement des sources de données très utiles visibles à l’aide de l’Observateur d’événements (Windows Event Log). Toute opération effectuée sur le système finit dans ce journal, où nous pouvons filtrer les évènements sur la base de plusieurs attributs (noms, dates, catégorie, niveau de sécurité, etc.). Chaque évènement généré contient un identifiant (ID) qui le catégorise, ainsi que plusieurs champs spécifiques donnant plus d’informations sur son contexte.
Parmi les ID d’authentification les plus courants, on peut mentionner les ID 4624, 4625 et 4634 :
– 4624 : Connexion réussie à un compte.
– 4625 : Échec de connexion à un compte.
– 4634 : Déconnexion d’un compte. Cet évènement montre que la session a été fermée et qu’elle n’existe plus.
L’Observateur d’événements est très pratique pour souligner toute activité inhabituelle. Ce sera la source de données avec laquelle nous travaillerons.
Tant que l’activité que nous cherchons à détecter est plus ou moins liée à des processus d’authentification, nous disposons d’évènements à son propos. Voici un exemple simple d’attaque par password spraying avec Hydra, un outil de cracking d’identifiants supportant de nombreux protocoles pour mener des attaques :
hydra -L users.txt -P passwords.txt 192.168.0.1 ssh -u -V
The events generated by such attacks (either brute-force or password spray) are mainly ID 4625 events (i.e. failed logons), at a rate between a second to a few milliseconds. Each event features multiple fields :
<EventData>
<Data Name="SubjectUserSid">S-1-5-18</Data>
<Data Name="SubjectUserName">DC01$</Data>
<Data Name="SubjectDomainName">CONTOSO</Data>
<Data Name="SubjectLogonId">0x3e7</Data>
<Data Name="TargetUserSid">S-1-0-0</Data>
<Data Name="TargetUserName">Auditor</Data>
<Data Name="TargetDomainName">CONTOSO</Data>
<Data Name="Status">0xc0000234</Data>
<Data Name="FailureReason">%%2307</Data>
<Data Name="SubStatus">0x0</Data>
<Data Name="LogonType">2</Data>
<Data Name="LogonProcessName">User32</Data>
<Data Name="AuthenticationPackageName">Negotiate</Data>
<Data Name="WorkstationName">DC01</Data>
<Data Name="TransmittedServices">-</Data>
<Data Name="LmPackageName">-</Data>
<Data Name="KeyLength">0</Data>
<Data Name="ProcessId">0x1bc</Data>
<Data Name="ProcessName">C:\Windows\System32\winlogon.exe</Data>
<Data Name="IpAddress">127.0.0.1</Data>
<Data Name="IpPort">0</Data>
</EventData>
Exemple XML issu de https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4625)
Après étude de plusieurs outils de brute-force et de password spraying, il apparait que ces attaques génèrent aussi quelques évènements sous les ID 4634 et 4624 (en particulier quand l’association identifiant-mot de passe est réussie).
Maintenant, comment les inclure dans un ensemble existant de données ?
En pratique : comment insérer des évènements malveillants dans un ensemble existant de données pour un effet réaliste ?
Notre base de données consiste en un ensemble d’évènements d’authentification bénins en provenance de plusieurs machines. La simple insertion d’évènements 4625 génériques (tels que ceux mentionnés plus haut) dans notre journal d’évènements inoffensifs ne serait pas très réaliste. Cela ajouterait plusieurs biais au modèle : les noms d’utilisateurs, les noms de domaines et les adresses IP ne correspondraient pas à de vrais noms, les horodatages pourraient être hors de l’intervalle effectif de dates de l’ensemble de données.
Pour que les évènements soient aussi réalistes que possible, certains champs doivent être modifiés en fonction du contexte, notamment : SubjectUserName, SubjectDomainName, TargetUserName, TargetDomainName, WorkstationName et IpAddress.
Comme évoqué plus tôt, il nous faut considérer notre base de données d’évènements bénins journalisés, à savoir, ceux qui contiennent des évènements d’audit de sécurité dans le journal d’évènements de Windows d’une machine sans activité malveillante. Pour disposer de données bénignes et de données « avec attaque » aux caractéristiques identiques (et entrainer un modèle sur la base des premières et prévoir les secondes), nous devons les scinder en deux parties chronologiquement, et tâcher d’insérer les attaques dans la seconde partie.
Le processus est le suivant :
- Premièrement : nous prenons n’importe quel événement dans la base de données. Nous obtenons une date, le nom de l’utilisateur, le domaine et l’adresse IP de la machine.
- Deuxièmement : nous rédigeons les autres champs pour chaque évènement à créer.
- Enfin : nous ajoutons ces évènements créés à l’ensemble des évènements bénins, selon un rythme et une répartition des identifiants spécifiques (censés être aussi proches qu’une vraie attaque).
Le schéma ci-dessous résume ce processus.
Insérer des évènements malveillants dans une base de données d’évènements bénins : l’API PowerShell pour tester la pertinence de notre approche dans une VM
Un moyen de tester si cette insertion est pertinente consiste dans l’utilisation d’un outil tiers de détection d’attaques par brute-force sur nos journaux modifiés, et la vérification de la détection de nos évènements malveillants. Il y a ici un bémol : nos journaux d’évènements sont dans un format CSV particulier, et la plupart des outils de détection d’attaques par brute-force (Zircolite, Chainsaw, Hayabusa) utilisent le format officiel EVTX de Microsoft. Bien qu’il existe plusieurs parseurs EVTX, nous n’avons pas trouvé d’outil de conversion vers le format EVTX. Aussi, il reste les outils de surveillance en temps réel (qui effectuent des détections sur les évènements à mesure qu’ils se produisent), par exemple, Splunk ou Wazuh. Néanmoins, ces outils lisent directement le journal d’évènements Windows. Aussi, pour voir s’ils détectent nos évènements, il nous faut les insérer directement dans ce journal de la machine.
En utilisant la fonction Powershell Write-EventLog, nous pouvons insérer des journaux d’authentification dans une machine virtuelle. Toutefois, cette API Powershell est assez limitée (seuls quelques champs de l’évènement peuvent être spécifiés, notamment l’ID, le message et le type d’entrée) : les évènements insérés ne sont donc pas identiques à ceux (plus détaillés) que nous avons intégrés dans nos fichiers CSV. Quoi qu’il en soit, avec Splunk dans la VM, nous avons pu détecter les évènements insérés.
Le modèle (entrainé) peut ensuite être testé sur de vrais évènements d’attaque en environnement contrôlé, comme les machines virtuelles de l’Active Directory que nous avons mis en place dans notre lab.
Conclusion : une manière simple, mais utile, de simuler des attaques
Certes, il s’agit ici d’un moyen simple de simuler des attaques, mais si le périmètre à étudier est restreint (nous ne considérons que les évènements de sécurité Windows liés à l’authentification), et pour des attaques simples comme des attaques par force brute, cette approche est plus que suffisante.
Plusieurs biais sont introduits par la répartition des évènements, leur nombre, leur horodatage, et le choix des machines attaquées, toutefois, en créant assez de variations de ces paramètres, la diversité des données générées (et de plusieurs biais) peut contrebalancer ces faiblesses initiales.
La force de cette approche tient dans le fait qu’elle permet — avec assez de données inoffensives — de générer facilement une grande quantité de données labélisées/étiquetées, avec suffisamment de variété. Il s’agit alors d’une bonne occasion de tester un modèle non supervisé de détection d’anomalies.