Dans ce tutoriel, nous allons construire un système d’analyse de journaux SIEM simplifié et parfumé à l’IA en utilisant Python. Notre focus sera sur l’analyse de journaux et la détection d’anomalies.

Nous allons parcourir l’ingestion des journaux, la détection d’anomalies avec un modèle d’apprentissage automatique léger, et même aborder comment le système pourrait répondre automatiquement.

Ce concept pratique illustrera comment l’IA peut améliorer la surveillance de la sécurité de manière pratique et accessible.

Table des matières

Qu’est-ce que les systèmes SIEM ?

Les systèmes de gestion des informations et des événements de sécurité (SIEM) sont le système nerveux central des opérations de sécurité modernes. Un SIEM regroupe et corrèle les journaux et les événements de sécurité de l’ensemble d’un environnement informatique pour fournir des informations en temps réel sur les incidents potentiels. Cela aide les organisations à détecter plus rapidement les menaces et à réagir plus rapidement.

Ces systèmes rassemblent de grandes quantités de données de journaux, des alertes de pare-feu aux journaux d’application, et les analysent à la recherche de signes de problèmes. La détection d’anomalies dans ce contexte est cruciale, et des motifs inhabituels dans les journaux peuvent révéler des incidents qui pourraient échapper aux règles statiques. Par exemple, une augmentation soudaine des demandes de réseau peut indiquer une attaque DDoS, tandis que de multiples tentatives de connexion échouées peuvent indiquer des tentatives d’accès non autorisées.

L’IA va plus loin que les capacités du SIEM. En exploitant des modèles d’IA avancés (comme de grands modèles de langage), un SIEM alimenté par l’IA peut analyser et interpréter intelligemment les journaux, apprendre à reconnaître ce à quoi ressemble un comportement « normal », et signaler les éléments « étranges » qui nécessitent une attention particulière.

En essence, l’IA peut agir comme un copilote intelligent pour les analystes, repérant des anomalies subtiles et même résumant les conclusions en langage clair. Les récents progrès réalisés dans les grands modèles de langage permettent aux SIEM de raisonner sur d’innombrables points de données de la même manière qu’un analyste humain le ferait, mais avec une vitesse et une échelle bien plus grandes. Le résultat est un puissant assistant de sécurité numérique qui aide à filtrer le bruit et à se concentrer sur les véritables menaces.

Prérequis

Avant de commencer, assurez-vous de disposer des éléments suivants :

  • Python 3.x installé sur votre système. Les exemples de code devraient fonctionner avec n’importe quelle version récente de Python.

  • Une familiarité de base avec la programmation Python (boucles, fonctions, utilisation de bibliothèques) et une compréhension des journaux (par exemple, à quoi ressemble une entrée de journal) seront utiles.

  • Bibliothèques Python : Nous utiliserons quelques bibliothèques courantes qui sont légères et ne nécessitent pas de matériel spécial :

    • pandas pour la manipulation de données de base (si vos journaux sont au format CSV ou similaire).

    • numpy pour les opérations numériques.

    • scikit-learn pour le modèle de détection d’anomalies (plus précisément, nous utiliserons l’algorithme IsolationForest).

  • Un ensemble de données de journal à analyser. Vous pouvez utiliser n’importe quel fichier journal (journaux système, journaux d’application, etc.) au format texte brut ou CSV. Pour la démonstration, nous simulerons un petit ensemble de données de journal afin que vous puissiez suivre même sans fichier journal préexistant.

Note: Si vous n’avez pas les bibliothèques mentionnées, installez-les via pip:

pip install pandas numpy scikit-learn

Mise en place du projet

Créons une structure de projet simple. Créez un nouveau répertoire pour ce projet de détection d’anomalies SIEM et naviguez jusqu’à l’intérieur. À l’intérieur, vous pouvez avoir un script Python (par exemple, siem_anomaly_demo.py) ou un notebook Jupyter pour exécuter le code étape par étape.

Assurez-vous que votre répertoire de travail contient ou peut accéder à vos données de journal. Si vous utilisez un fichier journal, il peut être judicieux de placer une copie dans ce dossier de projet. Pour notre preuve de concept, puisque nous allons générer des données de journal synthétiques, nous n’aurons pas besoin d’un fichier externe – mais dans un scénario réel, vous en auriez besoin.

Étapes de configuration du projet:

  1. Initialiser l’environnement – Si vous préférez, créez un environnement virtuel pour ce projet (optionnel mais une bonne pratique) :

     python -m venv venv
     source venv/bin/activate  # Sur Windows, utilisez "venv\Scripts\activate"
    

    Ensuite, installez les packages nécessaires dans cet environnement virtuel.

  2. Préparer une source de données – Identifiez la source de journaux que vous souhaitez analyser. Il peut s’agir d’un chemin vers un fichier journal ou une base de données. Assurez-vous de connaître le format des journaux (par exemple, sont-ils séparés par des virgules, des lignes JSON ou du texte brut ?). À titre d’illustration, nous fabriquerons quelques entrées de journal.

  3. Configurer votre script ou notebook – Ouvrez votre fichier Python ou notebook. Nous commencerons par importer les bibliothèques nécessaires et configurer toutes les configurations (comme les graines aléatoires pour la reproductibilité).

À la fin de cette configuration, vous devriez avoir un environnement Python prêt à exécuter notre code d’analyse des journaux SIEM, et soit un véritable ensemble de données de journaux, soit l’intention de simuler des données avec moi.

Implémentation de l’analyse des journaux

Dans un système SIEM complet, l’analyse des journaux consiste à collecter des journaux provenant de diverses sources et à les analyser dans un format uniforme pour un traitement ultérieur. Les journaux contiennent souvent des champs comme l’horodatage, le niveau de gravité, la source, le message d’événement, l’identifiant utilisateur, l’adresse IP, etc. La première tâche consiste à ingérer et à prétraiter ces journaux.

1. Ingestion des journaux

Si vos journaux sont dans un fichier texte, vous pouvez les lire en Python. Par exemple, si chaque entrée de journal est une ligne dans le fichier, vous pourriez faire :

with open("my_logs.txt") as f:
    raw_logs = f.readlines()

Si les journaux sont structurés (par exemple, au format CSV avec des colonnes), Pandas peut grandement simplifier la lecture :

import pandas as pd
df = pd.read_csv("my_logs.csv")
print(df.head())

Cela vous donnera un DataFrame df avec vos entrées de journaux organisées en colonnes. Mais de nombreux journaux sont semi-structurés (par exemple, des composants séparés par des espaces ou des caractères spéciaux). Dans de tels cas, vous pourriez avoir besoin de diviser chaque ligne par un délimiteur ou d’utiliser des expressions régulières pour extraire des champs. Par exemple, imaginez une ligne de journal :

2025-03-06 08:00:00, INFO, User login success, user: admin

Celle-ci a un horodatage, un niveau de journal, un message et un utilisateur. Nous pouvons analyser de telles lignes avec les méthodes de chaîne de Python :

logs = [
    "2025-03-06 08:00:00, INFO, User login success, user: admin",
    "2025-03-06 08:01:23, INFO, User login success, user: alice",
    "2025-03-06 08:02:45, ERROR, Failed login attempt, user: alice",
    # ... (plus de lignes de journal)
]
parsed_logs = []
for line in logs:
    parts = [p.strip() for p in line.split(",")]
    timestamp = parts[0]
    level = parts[1]
    message = parts[2]
    user = parts[3].split(":")[1].strip() if "user:" in parts[3] else None
    parsed_logs.append({"timestamp": timestamp, "level": level, "message": message, "user": user})

# Convertir en DataFrame pour une analyse plus facile
df_logs = pd.DataFrame(parsed_logs)
print(df_logs.head())

L’exécution de ce qui précède sur notre liste d’exemples produirait quelque chose comme :

            timestamp  level                 message   user
0  2025-03-06 08:00:00   INFO    User login success   admin
1  2025-03-06 08:01:23   INFO    User login success   alice
2  2025-03-06 08:02:45  ERROR  Failed login attempt   alice
...

Maintenant, nous avons structuré les journaux dans un tableau. Dans un scénario réel, vous continueriez à parser tous les champs pertinents de vos journaux (par exemple, les adresses IP, les codes d’erreur, etc.) en fonction de ce que vous souhaitez analyser.

2. Prétraitement et extraction de caractéristiques

Avec les journaux dans un format structuré, l’étape suivante consiste à dériver des caractéristiques pour la détection d’anomalies. Les messages de journal brut (chaînes) en eux-mêmes sont difficiles à apprendre directement pour un algorithme. Nous extrayons souvent des caractéristiques numériques ou des catégories qui peuvent être quantifiées. Quelques exemples de caractéristiques pourraient être :

  • Nombre d’événements : nombre d’événements par minute/heure, nombre d’échecs de connexion pour chaque utilisateur, etc.

  • Durée ou taille : si les journaux incluent des durées ou des tailles de données (par exemple, taille de transfert de fichier, temps d’exécution de requête), ces valeurs numériques peuvent être utilisées directement.

  • Encodage catégorique : les niveaux de journal (INFO, ERROR, DEBUG) pourraient être mappés à des nombres, ou des types d’événements spécifiques pourraient être encodés en one-hot.

Pour cette preuve de concept, concentrons-nous sur une fonctionnalité numérique simple : le nombre de tentatives de connexion par minute pour un utilisateur donné. Nous simulerons cela en tant que nos données de fonctionnalité.

Dans un système réel, vous le calculeriez en regroupant les entrées de journal analysées par fenêtre de temps et par utilisateur. L’objectif est d’obtenir un tableau de nombres où chaque nombre représente « combien de tentatives de connexion ont eu lieu en une minute donnée ». La plupart du temps, ce nombre sera faible (comportement normal), mais si une minute particulière a connu un nombre anormalement élevé de tentatives, cela constitue une anomalie (possiblement une attaque par force brute).

Pour simuler, nous allons générer une liste de 50 valeurs représentant un comportement normal, puis ajouter quelques valeurs qui sont anormalement élevées :

import numpy as np

# Simuler 50 minutes de compte de tentatives de connexion normales (environ 5 par minute en moyenne)
np.random.seed(42)  # pour exemple reproductible
normal_counts = np.random.poisson(lam=5, size=50)

# Simuler une anomalie : un pic de tentatives de connexion (par exemple, un attaquant essaie plus de 30 fois en une minute)
anomalous_counts = np.array([30, 40, 50])

# Combinez les données
login_attempts = np.concatenate([normal_counts, anomalous_counts])
print("Login attempts per minute:", login_attempts)

Lorsque vous exécutez le code ci-dessus, login_attempts pourrait ressembler à cela :

Login attempts per minute: [ 5  4  4  5  5  3  5  ...  4 30 40 50]

La plupart des valeurs sont à un chiffre, mais à la fin, nous avons trois minutes avec 30, 40 et 50 tentatives – des valeurs aberrantes claires. Ce sont nos données préparées pour la détection d’anomalies. Dans une analyse de journal réelle, ce type de données peut provenir du comptage d’événements dans vos journaux au fil du temps ou de l’extraction d’une certaine mesure du contenu du journal.

Maintenant que nos données sont prêtes, nous pouvons passer à la construction du modèle de détection d’anomalies.

Comment construire le modèle de détection des anomalies

Pour détecter les anomalies dans nos données dérivées des journaux, nous utiliserons une approche d’apprentissage automatique. Plus précisément, nous utiliserons une Forêt d’Isolation – un algorithme populaire pour la détection des anomalies non supervisée.

La Forêt d’Isolation fonctionne en partitionnant les données de manière aléatoire et en isolant les points. Les anomalies sont ces points qui sont rapidement isolés (séparés des autres), c’est-à-dire en moins de divisions aléatoires. Cela le rend excellent pour identifier les valeurs aberrantes dans un ensemble de données sans avoir besoin d’étiquettes (nous n’avons pas besoin de savoir à l’avance quelles entrées de journal sont « mauvaises »).

Pourquoi la Forêt d’Isolation?

  • Elle est efficace et fonctionne bien même si nous avons beaucoup de données.

  • Elle ne suppose aucune distribution spécifique des données (contrairement à certaines méthodes statistiques).

  • Elle nous donne une manière directe d’évaluer les anomalies.

Entraînons une Forêt d’Isolation sur nos données de tentatives_de_connexion:

from sklearn.ensemble import IsolationForest

# Préparez les données dans la forme attendue par le modèle (échantillons, caractéristiques)
X = login_attempts.reshape(-1, 1)  # chaque échantillon est un [nombre] unidimensionnel

# Initialisez le modèle Isolation Forest
model = IsolationForest(contamination=0.05, random_state=42)
# contamination=0.05 signifie que nous nous attendons à ce qu'environ 5% des données soient des anomalies

# Entraînez le modèle sur les données
model.fit(X)

Quelques notes sur le code :

  • Nous avons remodelé login_attempts en un tableau 2D X avec une colonne de caractéristiques car scikit-learn nécessite un tableau 2D pour l’entraînement (fit).

  • Nous avons défini contamination=0.05 pour donner au modèle un indice que environ 5% des données pourraient être des anomalies. Dans nos données synthétiques, nous avons ajouté 3 anomalies sur 53 points, ce qui représente ~5.7%, donc 5% est une estimation raisonnable. (Si vous ne spécifiez pas la contamination, l’algorithme choisira une valeur par défaut basée sur une hypothèse ou utilisera une valeur par défaut de 0.1 dans certaines versions.)

  • random_state=42 assure simplement la reproductibilité.

À ce stade, le modèle Isolation Forest a été entraîné sur nos données. En interne, il a construit un ensemble d’arbres aléatoires qui partitionnent les données. Les points difficiles à isoler (c’est-à-dire dans le cluster dense des points normaux) se retrouvent profondément dans ces arbres, tandis que les points faciles à isoler (les anomalies) se retrouvent avec des chemins plus courts.

Ensuite, nous utiliserons ce modèle pour identifier les points de données considérés comme anormaux.

Test et Visualisation des Résultats

Arrive maintenant la partie excitante : utiliser notre modèle entraîné pour détecter les anomalies dans les données de journal. Nous ferons en sorte que le modèle prédise des étiquettes pour chaque point de données, puis filtrons ceux signalés comme anomalies.

# Utiliser le modèle pour prédire les anomalies
labels = model.predict(X)
# Le modèle produit +1 pour les points normaux et -1 pour les anomalies

# Extraire les indices et les valeurs des anomalies
anomaly_indices = np.where(labels == -1)[0]
anomaly_values = login_attempts[anomaly_indices]

print("Anomaly indices:", anomaly_indices)
print("Anomaly values (login attempts):", anomaly_values)

Dans notre cas, nous nous attendons à ce que les anomalies soient les grands nombres que nous avons insérés (30, 40, 50). La sortie pourrait ressembler à :

Anomaly indices: [50 51 52]
Anomaly values (login attempts): [30 40 50]

Même sans rien savoir spécifiquement sur les « tentatives de connexion », l’Isolation Forest a reconnu ces valeurs comme étant en dehors du reste des données.

C’est la puissance de la détection des anomalies dans un contexte de sécurité : nous ne savons pas toujours à quoi ressemblera une nouvelle attaque, mais si elle provoque un écart important par rapport aux modèles normaux (comme un utilisateur effectuant soudainement 10 fois plus de tentatives de connexion que d’habitude), le détecteur d’anomalies met en lumière cette situation.

Visualisation des résultats

Dans une analyse réelle, il est souvent utile de visualiser les données et les anomalies. Par exemple, nous pourrions tracer les valeurs de login_attempts au fil du temps (minute par minute) et mettre en évidence les anomalies dans une couleur différente.

Dans ce cas simple, un graphique linéaire montrerait une ligne généralement plate autour de 3 à 8 connexions/min avec trois énormes pics à la fin. Ces pics sont nos anomalies. Vous pourriez réaliser cela avec Matplotlib si vous exécutez cela dans un notebook :

import matplotlib.pyplot as plt

plt.plot(login_attempts, label="Login attempts per minute")
plt.scatter(anomaly_indices, anomaly_values, color='red', label="Anomalies")
plt.xlabel("Time (minute index)")
plt.ylabel("Login attempts")
plt.legend()
plt.show()

Pour une sortie textuelle comme nous l’avons ici, les résultats imprimés confirment déjà que les valeurs élevées ont été détectées. Dans des cas plus complexes, les modèles de détection des anomalies fournissent également un score d’anomalie pour chaque point (par exemple, à quelle distance il se trouve de la plage normale). L’IsolationForest de Scikit-learn, par exemple, a une méthode decision_function qui produit un score (où des scores plus bas signifient plus d’anomalies).

Pour simplifier, nous n’allons pas approfondir les scores ici, mais il est bon de savoir que vous pouvez les récupérer pour classer les anomalies par gravité.

Avec la détection des anomalies en fonctionnement, que pouvons-nous faire lorsque nous trouvons une anomalie ? Cela nous amène à réfléchir aux réponses automatisées.

Possibilités de réponse automatisée

Détecter une anomalie n’est que la moitié de la bataille — la prochaine étape consiste à y répondre. Dans les systèmes SIEM d’entreprise, la réponse automatisée (souvent associée au SOAR – Orchestration de la Sécurité, Automatisation et Réponse) peut réduire considérablement le temps de réaction aux incidents.

Que pourrait faire un SIEM alimenté par l’IA lorsqu’il signale quelque chose d’inhabituel ? Voici quelques possibilités :

  • Alerte : La première action consiste à envoyer une alerte au personnel de sécurité. Cela pourrait être un e-mail, un message Slack ou la création d’un ticket dans un système de gestion des incidents. L’alerte contiendrait des détails sur l’anomalie (par exemple, “L’utilisateur alice a eu 50 tentatives de connexion échouées en 1 minute, ce qui est anormal”). GenAI peut aider ici en générant un résumé clair en langage naturel de l’incident pour l’analyste.

  • Atténuation automatisée : Des systèmes plus avancés pourraient prendre des mesures directes. Par exemple, si une adresse IP montre un comportement malveillant dans les journaux, le système pourrait automatiquement bloquer cette IP sur le pare-feu. Dans notre exemple de pic de connexion, le système pourrait temporairement verrouiller le compte utilisateur ou demander une authentification supplémentaire, en supposant qu’il pourrait s’agir d’une attaque de bot. Les SIEM basés sur l’IA aujourd’hui peuvent effectivement déclencher des actions de réponse prédéfinies ou même orchestrer des flux de travail complexes lorsque certaines menaces sont détectées (voir AI SIEM : Comment le SIEM avec IA/ML révolutionne le SOC | Exabeam pour plus d’informations).

  • Support d’enquête : L’IA générative pourrait également être utilisée pour recueillir automatiquement du contexte. Par exemple, lors de la détection de l’anomalie, le système pourrait extraire des journaux connexes (événements environnants, autres actions effectuées par le même utilisateur ou à partir de la même adresse IP) et fournir un rapport agrégé. Cela évite à l’analyste d’interroger manuellement plusieurs sources de données.

Il est important de mettre en œuvre des réponses automatisées avec précaution – vous ne voulez pas que le système réagisse de manière excessive à des faux positifs. Une stratégie courante est une réponse par niveaux : les anomalies à faible confiance pourraient simplement enregistrer un avertissement ou envoyer une alerte de faible priorité, tandis que les anomalies à haute confiance (ou les combinaisons d’anomalies) déclenchent des mesures de défense actives.

Dans la pratique, un SIEM alimenté par l’IA s’intégrerait à votre infrastructure (via des API, des scripts, etc.) pour exécuter ces actions. Pour notre PoC en Python, vous pourriez simuler une réponse automatisée en, disons, imprimant un message ou en appelant une fonction fictive lorsqu’une anomalie est détectée. Par exemple :

if len(anomaly_indices) > 0:
    print(f"Alert! Detected {len(anomaly_indices)} anomalous events. Initiating response procedures...")
    # Ici, vous pourriez ajouter du code pour désactiver un utilisateur ou notifier un administrateur, etc.

Bien que notre démonstration soit simple, il est facile d’imaginer l’extension de cela. Le SIEM pourrait, par exemple, alimenter des anomalies dans un modèle génératif plus large qui évalue la situation et décide de la meilleure ligne de conduite (comme un assistant Ops chatbot qui connaît vos runbooks). Les possibilités d’automatisation s’élargissent à mesure que l’IA devient plus sophistiquée.

Conclusion

Dans ce tutoriel, nous avons construit un composant SIEM de base alimenté par l’IA qui ingère des données de journal, les analyse à la recherche d’anomalies à l’aide d’un modèle d’apprentissage automatique et identifie des événements inhabituels qui pourraient représenter des menaces à la sécurité.

Nous avons commencé par analyser et préparer les données de journal, puis utilisé un modèle Isolation Forest pour détecter les valeurs aberrantes dans un flux de tentatives de connexion. Le modèle a réussi à signaler des comportements anormaux sans aucune connaissance préalable de ce à quoi ressemble une « attaque » – il s’est simplement appuyé sur des écarts par rapport aux modèles normaux appris.

Nous avons également discuté de la manière dont un tel système pourrait répondre aux anomalies détectées, en alertant les humains ou en prenant automatiquement des mesures.

Les systèmes SIEM modernes augmentés avec l’IA/ML vont dans cette direction : non seulement ils détectent les problèmes, mais ils aident également au triage et à y répondre. L’IA générative améliore encore cela en apprenant des analystes et en fournissant des résumés et des décisions intelligents, devenant ainsi un assistant infatigable au sein du Centre des Opérations de Sécurité.

Pour les prochaines étapes et améliorations :

  • Vous pouvez essayer cette approche sur des données de journal réelles. Par exemple, prenez un fichier journal système et extrayez une caractéristique comme « nombre de journaux d’erreurs par heure » ou « octets transférés par session » et lancez une détection d’anomalies dessus.

  • Expérimentez avec d’autres algorithmes comme le SVM à classe unique ou le Facteur Local d’Aberration pour la détection d’anomalies et voyez comment ils se comparent.

  • Intégrez un modèle de langage simple pour analyser les lignes de journal ou expliquer les anomalies. Par exemple, un LLM pourrait lire une entrée de journal anormale et suggérer ce qui pourrait ne pas aller (« Cette erreur signifie généralement que la base de données est inaccessible »).

  • Étendez les fonctionnalités : dans un véritable SIEM, vous utiliseriez de nombreux signaux en même temps (comptage des échecs de connexion, géolocalisation IP inhabituelle, noms de processus rares dans les journaux, et ainsi de suite). Plus de fonctionnalités et de données peuvent améliorer le contexte de détection.