Découverte de CrowdSec 1.5 et création d’un scénario de notification sous Windows Server
Sommaire
I. Présentation
Une nouvelle version de CrowdSec est disponible, et pas n'importe quelle version puisque CrowdSec 1.5 est considéré comme la plus grosse mise à jour depuis la sortie de la version 1.0. À cette occasion, nous vous proposons un article qui évoque les nouveautés de cette nouvelle mouture, avec la mise en pratique d'un scénario de notifications sous Windows Server !
II. Les nouveautés de CrowdSec 1.5
CrowdSec 1.5 contient une liste de nouveautés conséquentes résumée en quelques points clés ci-dessous :
- Kubernetes
Alors qu'il était déjà possible de protéger les services au sein de Kubernetes, CrowdSec 1.5 permet d'aller plus loin puisqu'il est possible de détecter les comportements malveillants au niveau du cluster ! Par exemple, la création d'un pod privilégié dans le cluster Kubernetes ou le brute force sur une API.
- Bucket S3
Les journaux stockés dans un bucket S3 peuvent être lus et analysés par CrowdSec, ce qui ouvre de nouvelles possibilités notamment pour certains services du Cloud AWS.
- AWS CloudTrail
Toujours en lien avec le Cloud AWS, CrowdSec 1.5 s'enrichit de nouvelles capacités de détection pour AWS CloudTrail. Par exemple, s'il y a un changement de configuration, un échec d'authentification sur la console, l'utilisation d'un compte "root", ou encore des changements sur un Security Group, CrowdSec pourra générer une alerte.
- Auditd
Sous Linux, le framework "auditd" est très important, car il permet de savoir ce qu'il s'est passé sur le système grâce à la création d'événements : accès aux fichiers, processus exécutés, commandes exécutées par les utilisateurs, etc... CrowdSec 1.5 est capable de lire les événements générés par auditd pour détecter des comportements suspects faisant suite à une compromission d'une machine. Par exemple, l'exécution à partir d'emplacements suspects, la récupération de fichiers (curl/wget) ou la suppression de données.
- CAPI Whitelist
La liste des adresses IP malveillantes alimentées par la communauté CrowdSec est très contrôlée. Malgré tout, il peut arriver qu'il y ait des faux positifs, comme avec toutes les listes de ce type. De ce fait, avec CrowdSec 1.5 il devient possible de créer une liste blanche qui s'applique aussi sur les adresses IP contenues dans la blocklist communautaire.
- Par ailleurs...
CrowdSec 1.5 devient encore plus flexible pour ceux qui maitrisent sa configuration puisqu'il sera possible d'activer de nouvelles fonctionnalités pour les tester (grâce à un système de flag), mais aussi de créer des règles avancées pour détecter des comportements malveillants plus complexes. Pour le premier point évoqué, les fonctionnalités disponibles peuvent être listées avec cette commande :
cscli config feature-flags
Enfin, la console CrowdSec commence à se doter de capacité lui permettant d'interagir directement avec les instances associées à votre compte (afin de pousser des ordres, de la configuration). Ce qui est très prometteur et ouvre beaucoup de possibilités : la prochaine partie de cet article évoque une première nouveauté qui va en ce sens.
III. Console CrowdSec : des blocklists d'adresses IP par thèmes
La sortie de CrowdSec 1.5 est accompagnée par une nouveauté dans la console CrowdSec : la section nommée "Blocklists". Pour rappel, la console CrowdSec est une interface web qui vous permet d'avoir une vue d'ensemble des menaces sur vos serveurs protégés par CrowdSec (nombre de menaces, origines, types d'attaques, version de CrowdSec, etc.).
Située sous le menu "Instances", la section "Blocklists" donne accès à un ensemble de listes d'adresses IP malveillantes, organisées par thèmes. Ces listes tierces ne sont pas gérées directement par CrowdSec, donc on peut estimer qu'il n'y aura pas le même niveau de fiabilité vis-à-vis des listes CrowdSec officielles.
Toutefois, c'est un plus très intéressant pour bloquer des adresses IP correspondantes à des cibles ou des usages particuliers (VPN, botnets, proxies SSL, etc.). Par exemple, la blocklist "CrowdSec WordPress List" permet de bloquer des adresses IP qui ont mauvaise réputation et qui sont connues pour s'attaquer aux sites WordPress.
Avec la console CrowdSec en version gratuite, il est possible de s'abonner à deux blocklists. Actuellement, trois listes sont réservées aux membres premiums tandis que les autres sont ouvertes à tous les utilisateurs. Quand on a fait son choix, il suffit de cliquer sur "Subscribe".
Cette action permet d'obtenir des détails supplémentaires sur la blocklist sélectionnée, mais aussi d'affecter cette liste à une ou plusieurs instances. Cette association entre une instance CrowdSec et la liste sélectionnée s'effectue via le bouton "Add instance(s)".
La liste des instances CrowdSec rattachées à votre compte "CrowdSec Console" s'affiche. À vous de sélectionner la ou les instances qui doivent bloquer les adresses IP contenues dans la blocklist. Lorsqu'une instance apparaît en grisée comme sur l'image ci-dessous, c'est qu'elle n'est pas suffisamment à jour. Au-delà de choisir une instance, on doit aussi choisir une action à réaliser (bannir, présenter un captcha, etc.).
Une fois l'association effectuée, l'instance apparaît dans le détail de la blocklist concernée.
Cette nouvelle fonctionnalité devrait satisfaire les utilisateurs qui souhaitent aller plus loin dans le blocage des adresses IP malveillantes. En effet, même si la liste de CrowdSec est déjà très complète et continuellement mise à jour, ces listes supplémentaires vont permettre de bloquer encore plus d'adresses IP malveillantes avant même qu'elles aient une chance d'attaquer votre serveur.
IV. Scénario Windows Server
Mes précédents articles au sujet de CrowdSec évoquaient les capacités de l'outil à détecter des comportements malveillants (brute force, scan, exploitation d'une CVE, etc.). Il faut savoir que l'on peut utiliser CrowdSec pour effectuer de l'audit (ou de la surveillance, si vous préférez) afin d'être notifié lorsqu'un événement se produit. Cet événement ne sera pas forcément malveillant, mais il peut être potentiellement suspect.
Ce que nous allons faire aujourd'hui, c'est configurer CrowdSec sous Windows (mais on pourrait le faire sur Linux aussi), de manière à :
- Surveiller les connexions RDP sur un serveur Windows Server (ici, on s'appuie sur l'événement 4624 du journal "Sécurité" de Windows)
- Envoyer une notification dans un canal Microsoft Teams (sous la forme d'un nouveau message) à chaque nouvelle connexion RDP sur le serveur
Et, pour aller encore plus loin, on peut affiner un peu plus :
- Envoyer une notification dans un canal Microsoft Teams (sous la forme d'un nouveau message) à chaque nouvelle connexion RDP sur le serveur, avec en supplément une alerte par e-mail lorsque la connexion a lieu le week-end ou en dehors des heures ouvrées (car là, potentiellement, ça peut être suspect).
Pour mettre en place ce nouveau scénario, la configuration de CrowdSec doit être modifiée. Ainsi, cet exemple pourra vous être utile, je l'espère, pour mettre en place d'autres scénarios.
Remarque : je pars du principe que CrowdSec 1.5 est installé sur mon serveur Windows Server. Ce serveur est autonome et l'accès RDP est actif.
A. Créer un nouveau parseur
Tout d'abord, on va devoir créer un nouveau parseur dans CrowdSec pour qu'il soit capable d'analyser les événements du journal "Sécurité" qui ont l'ID "4624". En effet, lorsqu'une connexion est effectuée sur le serveur, un nouvel événement avec cet ID est généré, et on peut obtenir l'adresse IP source et le nom du compte. D'ailleurs, ici je parle de connexions RDP, mais on est sur de l'ouverture de session au sens large avec cet ID. Par exemple :
Cet événement va devoir être "capturé" et analysé par CrowdSec.
De ce fait, nous allons créer un nouveau fichier YAML nommé "windows-success-auth.yaml" à cet endroit :
C:\ProgramData\CrowdSec\config\parsers\s01-parse\windows-success-auth.yaml
Dans ce fichier, plutôt que de repartir de zéro, nous allons réutiliser le contenu du fichier "windows-auth.yaml" ce qui nous donne une base. En effet, ce fichier sert à détecter les attaques par brute force en regardant les événements avec l'ID 4625 (échec d'ouverture de session). Il est déjà capable de récupérer l'adresse IP source et le nom de l'utilisateur.
Seules quelques valeurs sont à modifier : on va remplacer l'EventID "4625" par "4624", donner un nouveau nom à ce parseur, et modifier la description. Ce qui donne :
En plus des valeurs à modifier, il y a deux lignes à ajouter pour permettre la récupération du nom de la machine via une meta que l'on appellera "hostname". De cette façon, la notification contiendra le nom de la machine sur laquelle l'utilisateur s'est connecté.
Voici le code du fichier :
onsuccess: next_stage #debug: true filter: "evt.Parsed.Channel == 'Security' && evt.Parsed.EventID == '4624'" name: crowdsecurity/windows-success-auth description: "Parse windows authentication success events (id 4624)" statics: - meta: source_ip expression: XMLGetNodeValue(evt.Line.Raw, "/Event/EventData[1]/Data[@Name='IpAddress']") - meta: username expression: XMLGetNodeValue(evt.Line.Raw, "/Event/EventData[1]/Data[@Name='TargetUserName']") - meta: hostname expression: evt.Parsed.Computer - meta: log_type value: windows_success_auth
Enregistrez ce fichier. Première étape validée.
B. Ajouter une nouvelle acquisition
Désormais, nous allons devoir indiquer à CrowdSec qu'il doit analyser les événements avec l'ID "4624" : ce qu'il est capable de faire grâce à notre nouveau parseur. Pour lui indiquer ce nouvel ID supplémentaire, on va éditer ce fichier :
C:\ProgramData\CrowdSec\config\acquis.yaml
Dans ce fichier, on ajoute simplement l'ID de cette façon :
Enregistrez ce fichier. Deuxième étape validée !
C. Créer un nouveau scénario
Place à la création d'un nouveau scénario dans le but de générer une alerte lorsqu'un nouvel événement sera détecté. Ensuite, nous verrons ce que l'on fait de cette alerte. Ce nouvel événement correspond à l'arrivée d'une nouvelle entrée de journal avec l'ID 4624.
Ce nouveau scénario sera décrit dans ce fichier :
C:\ProgramData\CrowdSec\config\scenarios\windows-succes-auth.yaml
Là encore, plutôt que de partir de zéro, on va utiliser le contenu du fichier "windows-bf.yaml" comme base. Toutefois, on a de nombreuses modifications à apporter.
Tout d'abord, le type doit être changé :
# Cette valeur : type: leaky # Devient : type: trigger
Avec le type "leaky", on cherche à remplir un bucket et quand il déborde, on bannit l'adresse IP. C'est cohérent puisque sur une attaque brute force RDP, on attend d'avoir plusieurs tentatives en échecs avant de bannir l'adresse IP à l'origine des tentatives. Ici, on veut recevoir une notification à chaque fois que l'événement se produit (on n'attend pas qu'il se produise X fois avant de notifier) donc on choisit le type "trigger".
Puisque l'on utilise le type "trigger", il y a plusieurs directives qui n'ont pas d'intérêt et que l'on va supprimer :
leakspeed: "10s" capacity: 5
Ensuite, on en profite pour adapter le filtre, car on va cibler notre parseur créé précédemment : "windows_success_auth". Enfin, on retire la partie remédiation, car ce n'est pas utile non plus :
remediation: true
Ce qui donne le fichier suivant :
Notez le nom du scénario :
crowdsecurity/windows-success-auth
Enregistrez ce fichier. Troisième étape validée !
D. Ajouter un nouveau profil
Pour finir, il faut ajuster le fichier "profiles.yaml" pour indiquer à CrowdSec ce qu'il doit faire lorsque notre scénario se déclenche. En ce qui nous concerne, nous souhaitons envoyer une notification sur Teams. Le fichier à éditer est le suivant :
C:\ProgramData\CrowdSec\config\profiles.yaml
Au sujet de ce fichier, il faut savoir que :
- Il y a déjà un profil par défaut nommé "default_ip_remediation" qui permet de bannir les adresses IP malveillantes pour une durée de 4 heures, lorsque la remédiation est activée
- La bonne pratique consiste à laisser ce profil par défaut à la fin du fichier.
- Chaque profil doit être séparé par "---" au risque d'avoir un problème de syntaxe YAML dans le fichier.
Nous allons ajouter un nouveau profil nommé "notif_windows_success_auth" au début du fichier. En guise de filtre, pour que ce profil se déclenche, nous souhaitons qu'il y ait une alerte sur le scénario "crowdsecurity/windows-success-auth" d'où l'utilisation de l'instruction Alert.GetScenario().
Que fait-on dans ce cas-là ? On active la notification sur le profil de notifications "teams" que nous allons créer par la suite. Ce qui donne ce bout de code :
name: notif_windows_success_auth filters: - Alert.Remediation == false && Alert.GetScenario() == "crowdsecurity/windows-success-auth" notifications: - teams on_success: break ---
Une fois intégré dans le fichier "profiles.yaml", on a :
Enregistrez ce fichier ! Il nous reste une dernière étape à réaliser.
E. Configurer la notification Microsoft Teams
Depuis le départ, j'évoque le fait d'avoir une notification dans Microsoft Teams lorsqu'il y aura une nouvelle connexion. Nous venons aussi de déclarer le profil de notifications "teams" dans le fichier "profiles.yaml". Toutefois, nous n'avons pas fait la configuration de cette connexion à Teams...!
Pour permettre l'envoi de message dans Microsoft Teams à partir d'une application externe, on utilise un webhook. Il s'agit d'un connecteur que l'on va créer dans un canal d'une équipe Teams et qui va permettre d'envoyer des messages.
Dans cet exemple, je souhaite que les notifications de CrowdSec soient diffusées dans le canal "Notifications CrowdSec" d'une équipe Teams. À savoir, ici :
Pour cela, il faut cliquer sur le canal, puis sur la droite ouvrir le menu en cliquant sur "..." et choisir "Connecteurs".
Dans la liste des connecteurs, recherchez "incoming" de manière à voir le connecteur "Webhook entrant" apparaître. Cliquez sur "Ajouter".
Une fois qu'il est ajouté, vous devez cliquer sur "Configurer" afin de donner un nom à votre Webhook, et éventuellement, un logo.
Au final, vous obtenez l'URL de votre Webhook. Cette URL doit être indiquée dans la configuration de CrowdSec, car elle doit être utilisée pour envoyer les messages.
Du côté de CrowdSec, créez ce fichier :
C:\ProgramData\CrowdSec\config\notifications\teams.yaml
Dans ce fichier, copiez-coller le contenu du modèle proposé sur le site de CrowdSec puisqu'il va nous servir de base :
Commencez par changer le nom de ce module de notification (on remet le même nom que dans le fichier "profiles.yaml") :
# Don't change this
type: http
name: teams # this must match with the registered plugin in the profile
Ce qui est important et essentiel, c'est de définir la propriété "url" pour indiquer l'URL du Webhook que vous venez de créer (en fin de fichier) :
# CrowdSec-Channel
url: https://it-connect.webhook.office.com/webhookb2/50969
Enfin, il faut savoir que la propriété "format" sert à configurer l'apparence et le contenu du message qui sera envoyé sur Microsoft Teams. Par défaut, ce modèle cherche à récupérer des informations sur les décisions associées à cette alerte : ici, il n'y en a pas. Nous devons ajuster le modèle pour qu'il soit fonctionnel avec notre scénario, sinon il y aura une erreur.
Le contenu de la propriété "format" est écrit en Go template. Je vous l'accorde, ce n'est pas évident au premier abord... Donc j'espère que cet exemple pourra aider ceux qui souhaitent se lancer. Voici le code mon template pour que la notification Microsoft Teams contienne le nom du serveur, l'adresse IP source et le nom de l'utilisateur qui s'est connecté.
format: | { "type": "message", "attachments": [ { "contentType": "application/vnd.microsoft.card.adaptive", "content": { "$schema": "https://adaptivecards.io/schemas/adaptive-card.json", "type": "AdaptiveCard", "version": "1.2", {{- range . -}} "body": [ { "type": "TextBlock", "text": "[Info] {{(GetMeta . "hostname")}} - Nouvelle connexion RDP", "wrap": true, "size": "large", "weight": "bolder", "fontType": "Default" }, { "type": "FactSet", "facts": [ { "title": "IP:", "value": "{{.Source.Value}}" }, { "title": "Reason:", "value": "{{.Scenario}}" }, { "title": "User:", "value": "{{(GetMeta . "username")}}" } ] }, { "type": "ActionSet", "actions": [ { "type": "Action.OpenUrl", "title": "Whois", "url": "https://www.whois.com/whois/{{ .Source.Value }}", "style": "positive" }, { "type": "Action.OpenUrl", "title": "Shodan", "url": "https://www.shodan.io/host/{{ .Source.Value }}", "style": "positive" }, { "type": "Action.OpenUrl", "title": "AbuseIPDB", "url": "https://www.abuseipdb.com/check/{{ .Source.Value }}", "style": "positive" } ] }, { "type": "ActionSet", "actions": [ { "type": "Action.OpenUrl", "title": "Unban IP in CAPI", "url": "https://crowdsec.net/unban-my-ip/", "style": "positive" } ], } {{- end -}} ] } } ] }
Enregistrez ce fichier ! Il ne reste plus qu'à tester, mais avant cela, pensez à relancer le service CrowdSec :
Restart-Service crowdsec
Note : si vous envisagez de recevoir des alertes dans Microsoft Teams relatives aux décisions, vous devez créer deux modèles de notifications Teams : un premier basé sur le template original pour les décisions et un second comme celui-ci pour les notifications sur simple événement.
F. Tester le bon fonctionnement
Pour tester le bon fonctionnement de notre configuration, rien de plus simple : il faut se connecter en "Bureau à distance" sur le serveur où CrowdSec est installé.
Ensuite, la notification dans Teams apparaît dans la seconde. Comme le montre l'image ci-dessous, on peut voir qu'elle contient aussi des boutons d'actions pour en savoir plus sur l'adresse IP source du client. En résumé, cette notification contient :
- Le nom du serveur sur lequel il y a une nouvelle connexion
- L'adresse IP à l'origine de cette connexion
- La raison de la notification (= le nom du scénario CrowdSec)
- L'utilisateur qui s'est connecté au serveur
Au-delà de recevoir le message sur Microsoft Teams, une alerte est visible via le CLI de CrowdSec en utilisant la commande suivante :
cscli alerts list --all
Si vous ne recevez rien dans Microsoft Teams ou si vous rencontrez un problème, pensez à consulter le fichier de log de CrowdSec :
C:\ProgramData\CrowdSec\log\crowdsec.log
Voilà, cette configuration touche à sa fin ! Toutefois, il nous reste le petit bonus à voir ensemble, pour ceux qui veulent aller plus loin.
G. Bonus : alerte e-mail pour les connexions hors périodes ouvrées
Lorsqu'un utilisateur se connecte sur le serveur le samedi, le dimanche, ou en dehors des heures ouvrées (admettons de 18h à 06h), nous souhaitons recevoir une alerte par e-mail, en plus de recevoir une notification Teams. Dans ce cas, on va commencer par compléter notre scénario créé précédemment (on pourrait aussi créer un nouveau fichier de scénario).
Dans ce fichier :
C:\ProgramData\CrowdSec\config\scenarios\windows-succes-auth.yaml
On va ajouter le bout de code suivant :
--- type: trigger #debug: true name: crowdsecurity/windows-success-auth-nwo description: "Detect Windows login outside of office hours" filter: | evt.Meta.log_type == 'windows_success_auth' && (evt.Time.Hour() >= 16 || evt.Time.Hour() < 4) || (evt.Time.Weekday().String() == 'Saturday' || evt.Time.Weekday().String() == 'Sunday') groupby: evt.Meta.source_ip blackhole: 1m reprocess: true labels: service: windows type: audit
Si ce n'est qu'on utilise un nom différent , c'est surtout le filtre qui est différent. Au-delà de récupérer les événements de "windows_success_auth", on ajoute une autre condition où l'on regarde l'heure et le jour de la semaine (soit 4 conditions avec l'opérateur "ou").
Note : l'heure doit être déterminée en tenant compte du fuseau horaire UTC, c'est pour cette raison que l'on indique "16" au lieu de "18" dans le filtre ci-dessus, afin de matcher avec 18h. Idem pour la valeur "4" au lieu de "6". CrowdSec ne peut pas être configuré pour utiliser un autre fuseau horaire.
Au final, on obtient le fichier suivant :
Enregistrez quand c'est fait.
Ensuite, c'est le fichier "profiles.yaml" qui doit être mis à jour. En effet, il faut que l'on ajoute une règle pour que si notre scénario matche, un e-mail soit envoyé.
C:\ProgramData\CrowdSec\config\profiles.yaml
Sur le même principe que pour le premier scénario, on va ajouter le bout de code ci-dessous où l'on appelle le profil de notification "email" au lieu de "teams".
--- name: notif_windows_success_auth_nwo filters: - Alert.Remediation == false && Alert.GetScenario() == "crowdsecurity/windows-success-auth-nwo" notifications: - email on_success: break
Ce qui donne :
Enfin, il restera à configurer le profil de notifications par e-mail. Cette configuration peut être effectuée via ce fichier :
C:\ProgramData\CrowdSec\config\notifications\email.yaml
Par défaut, le profil se nomme "email_default" donc pensez à changer le nom en "email" si vous utilisez mon exemple. Ensuite, il faudra configurer les informations de connexion à votre serveur SMTP : serveur SMTP, nom d'utilisateur, mot de passe, port, adresse e-mail de l'expéditeur, etc... Ici, ce sera propre à chaque infrastructure.
Remarque : pour cet exemple, je me suis appuyé sur le service Amazon SES.
Voici un exemple (qui donne le rendu ci-dessus) :
format: | <html><body> {{range . -}} <p>Serveur : {{(GetMeta . "hostname")}}</p> <p>L'adresse IP {{.Source.Value}} est à l'origine d'une nouvelle connexion avec l'utilisateur {{(GetMeta . "username")}}</p> {{end -}} </body></html> smtp_host: email-smtp.eu-west-3.amazonaws.com smtp_username: MonUserAmazonSES smtp_password: MonMotDePasseAmazonSES smtp_port: 587 # Common values are any of [25, 465, 587, 2525] auth_type: login # Valid choices are "none", "crammd5", "login", "plain" sender_name: CrowdSec sender_email: [email protected] email_subject: "CrowdSec Notification" receiver_emails: - [email protected] # One of "ssltls", "starttls", "none" encryption_type: starttls
En plus, vous pouvez lire la documentation officielle :
Il ne restera plus qu'à relancer CrowdSec et à tester !
Restart-Service crowdsec
V. Conclusion
Cet article de présentation de CrowdSec 1.5 touche à sa fin ! Ce nouvel exemple concret sous Windows Server montre un autre cas d'usage de CrowdSec et on voit que cet outil n'est pas limité à la détection de menaces. Il est suffisamment personnalisable pour générer des alertes selon des événements et à destination d’un ou plusieurs canaux. Ici, le mode de notifications "HTTP" est utilisé via Microsoft Teams, mais il existe plein d'autres solutions compatibles.
Enfin, sachez qu'en environnement Active Directory, le journal "Sécurité" pourra être alimenté avec des ID différents, et surtout, l'événement ne sera pas forcément généré sur le serveur sur lequel on souhaite se connecter : tout dépend du compte que l'on utilise.
Maintenant, c'est à vous de jouer, à vous d'installer CrowdSec 1.5 !
Mais quelle usine à gaz ! Et d’ailleurs, c’est à ne rien y comprendre.
Merci Flo, sympa je cherchais un truc du genre en plus!
Par contre je me fait spam avec utilisateurs NOMDUSERVEUR$ depuis l’ipv6 localhost ::1
Pour palier à ça, j’ai rajouté un filtre evt.Meta.source_ip != ‘::1’ sur le parser pour exclure cette notif 😉
Hello Maxime,
Merci pour ton retour et pour ce tips ! 🙂