Analyse des artefacts système Linux
Quand l'utiliser
- Lors de l'investigation d'un serveur ou poste de travail Linux compromis
- Pour identifier les mécanismes de persistance (cron, systemd, clés SSH)
- Lors du traçage de l'activité utilisateur via l'historique shell et les journaux d'authentification
- Pendant la réponse à incident pour déterminer l'étendue d'une brèche Linux
- Pour détecter les rootkits, backdoors et modifications non autorisées
Prérequis
- Image forensique ou accès live au système Linux (lecture seule)
- Compréhension de la hiérarchie du système de fichiers Linux (FHS)
- Connaissance des emplacements courants des journaux Linux (/var/log/)
- Outils : chkrootkit, rkhunter, AIDE, journaux auditd
- Familiarité avec systemd, cron et les configurations PAM
- Accès root pour une collecte complète des artefacts
Workflow
Étape 1 : Monter et collecter les artefacts système
# Monter l'image forensique en lecture seule
mount -o ro,loop,offset=$((2048*512)) /cases/case-2024-001/images/linux_evidence.dd /mnt/evidence
# Créer les répertoires de collecte
mkdir -p /cases/case-2024-001/linux/{logs,config,users,persistence,network}
# Collecter les journaux d'authentification
cp /mnt/evidence/var/log/auth.log* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/secure* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/syslog* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/kern.log* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/audit/audit.log* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/wtmp /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/btmp /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/lastlog /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/faillog /cases/case-2024-001/linux/logs/
# Collecter les artefacts utilisateur
for user_dir in /mnt/evidence/home/*/; do
username=$(basename "$user_dir")
mkdir -p /cases/case-2024-001/linux/users/$username
cp "$user_dir"/.bash_history /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.zsh_history /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp -r "$user_dir"/.ssh/ /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.bashrc /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.profile /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.viminfo /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.wget-hsts /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.python_history /cases/case-2024-001/linux/users/$username/ 2>/dev/null
done
# Collecter les artefacts de l'utilisateur root
cp /mnt/evidence/root/.bash_history /cases/case-2024-001/linux/users/root/ 2>/dev/null
cp -r /mnt/evidence/root/.ssh/ /cases/case-2024-001/linux/users/root/ 2>/dev/null
# Collecter la configuration système
cp /mnt/evidence/etc/passwd /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/shadow /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/group /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/sudoers /cases/case-2024-001/linux/config/
cp -r /mnt/evidence/etc/sudoers.d/ /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/hosts /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/resolv.conf /cases/case-2024-001/linux/config/
cp -r /mnt/evidence/etc/ssh/ /cases/case-2024-001/linux/config/
Étape 2 : Analyser les comptes utilisateur et l'authentification
# Analyser les comptes utilisateur pour les anomalies
python3 << 'PYEOF'
print("=== ANALYSE DES COMPTES UTILISATEUR ===\n")
# Analyser /etc/passwd
with open('/cases/case-2024-001/linux/config/passwd') as f:
for line in f:
parts = line.strip().split(':')
if len(parts) >= 7:
username, _, uid, gid, comment, home, shell = parts[0], parts[1], int(parts[2]), int(parts[3]), parts[4], parts[5], parts[6]
# Signaler les comptes avec UID 0 (équivalent root)
if uid == 0 and username != 'root':
print(f" ALERTE : Compte UID 0 : {username} (shell : {shell})")
# Signaler les comptes avec un shell de connexion qui n'en devraient pas avoir
if shell not in ('/bin/false', '/usr/sbin/nologin', '/bin/sync') and uid >= 1000:
print(f" Utilisateur : {username} (UID:{uid}, Shell:{shell}, Home:{home})")
# Signaler les comptes système avec des shells de connexion
if uid < 1000 and uid > 0 and shell in ('/bin/bash', '/bin/sh', '/bin/zsh'):
print(f" ATTENTION : Compte système avec shell : {username} (UID:{uid}, Shell:{shell})")
# Analyser /etc/shadow pour l'état des mots de passe
print("\n=== ÉTAT DES MOTS DE PASSE ===")
with open('/cases/case-2024-001/linux/config/shadow') as f:
for line in f:
parts = line.strip().split(':')
if len(parts) >= 3:
username = parts[0]
pwd_hash = parts[1]
last_change = parts[2]
if pwd_hash and pwd_hash not in ('*', '!', '!!', ''):
hash_type = 'Inconnu'
if pwd_hash.startswith('$6$'): hash_type = 'SHA-512'
elif pwd_hash.startswith('$5$'): hash_type = 'SHA-256'
elif pwd_hash.startswith('$y$'): hash_type = 'yescrypt'
elif pwd_hash.startswith('$1$'): hash_type = 'MD5 (FAIBLE)'
print(f" {username} : hash {hash_type}, dernière modification : jour {last_change}")
PYEOF
# Analyser l'historique de connexion
last -f /cases/case-2024-001/linux/logs/wtmp > /cases/case-2024-001/linux/analysis/login_history.txt
lastb -f /cases/case-2024-001/linux/logs/btmp > /cases/case-2024-001/linux/analysis/failed_logins.txt 2>/dev/null
Étape 3 : Examiner les mécanismes de persistance
# Vérifier les tâches cron pour tous les utilisateurs
echo "=== TÂCHES CRON ===" > /cases/case-2024-001/linux/persistence/cron_analysis.txt
# Cron système
for cronfile in /mnt/evidence/etc/crontab /mnt/evidence/etc/cron.d/*; do
echo "--- $cronfile ---" >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
cat "$cronfile" 2>/dev/null >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
echo "" >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
done
# Crontabs utilisateur
for cronfile in /mnt/evidence/var/spool/cron/crontabs/*; do
echo "--- Crontab utilisateur : $(basename $cronfile) ---" >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
cat "$cronfile" 2>/dev/null >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
echo "" >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
done
# Vérifier les services systemd pour la persistance
echo "=== SERVICES SYSTEMD ===" > /cases/case-2024-001/linux/persistence/systemd_analysis.txt
find /mnt/evidence/etc/systemd/system/ -name "*.service" -newer /mnt/evidence/etc/os-release \
>> /cases/case-2024-001/linux/persistence/systemd_analysis.txt
for svc in /mnt/evidence/etc/systemd/system/*.service; do
echo "--- $(basename $svc) ---" >> /cases/case-2024-001/linux/persistence/systemd_analysis.txt
cat "$svc" >> /cases/case-2024-001/linux/persistence/systemd_analysis.txt
echo "" >> /cases/case-2024-001/linux/persistence/systemd_analysis.txt
done
# Vérifier les clés SSH autorisées (détection de backdoor)
echo "=== CLÉS SSH AUTORISÉES ===" > /cases/case-2024-001/linux/persistence/ssh_keys.txt
find /mnt/evidence/home/ /mnt/evidence/root/ -name "authorized_keys" -exec sh -c \
'echo "--- {} ---"; cat {}; echo ""' \; >> /cases/case-2024-001/linux/persistence/ssh_keys.txt
# Vérifier rc.local et les scripts d'initialisation
cat /mnt/evidence/etc/rc.local 2>/dev/null > /cases/case-2024-001/linux/persistence/rc_local.txt
# Vérifier /etc/profile.d/ pour les scripts déclenchés par connexion
ls -la /mnt/evidence/etc/profile.d/ > /cases/case-2024-001/linux/persistence/profile_scripts.txt
# Vérifier le détournement LD_PRELOAD
grep -r "LD_PRELOAD" /mnt/evidence/etc/ 2>/dev/null > /cases/case-2024-001/linux/persistence/ld_preload.txt
cat /mnt/evidence/etc/ld.so.preload 2>/dev/null >> /cases/case-2024-001/linux/persistence/ld_preload.txt
Étape 4 : Analyser l'historique shell et l'exécution de commandes
# Analyser l'historique bash pour chaque utilisateur
python3 << 'PYEOF'
import os, glob
print("=== ANALYSE DE L'HISTORIQUE SHELL ===\n")
suspicious_commands = [
'wget', 'curl', 'nc ', 'ncat', 'netcat', 'python -c', 'python3 -c',
'perl -e', 'base64', 'chmod 777', 'chmod +s', '/dev/tcp', '/dev/udp',
'nmap', 'masscan', 'hydra', 'john', 'hashcat', 'passwd', 'useradd',
'iptables -F', 'ufw disable', 'history -c', 'rm -rf /', 'dd if=',
'crontab', 'at ', 'systemctl enable', 'ssh-keygen', 'scp ', 'rsync',
'tar czf', 'zip -r', 'openssl enc', 'gpg --encrypt', 'shred',
'chattr', 'setfacl', 'awk', '/tmp/', '/dev/shm/'
]
for hist_file in glob.glob('/cases/case-2024-001/linux/users/*/.bash_history'):
username = hist_file.split('/')[-2]
print(f"Utilisateur : {username}")
with open(hist_file, 'r', errors='ignore') as f:
lines = f.readlines()
print(f" Total de commandes : {len(lines)}")
flagged = []
for i, line in enumerate(lines):
line = line.strip()
for cmd in suspicious_commands:
if cmd in line.lower():
flagged.append((i+1, line))
break
if flagged:
print(f" Commandes suspectes : {len(flagged)}")
for lineno, cmd in flagged:
print(f" Ligne {lineno} : {cmd[:120]}")
print()
PYEOF
Étape 5 : Vérifier les rootkits et les binaires modifiés
# Vérifier les indicateurs de rootkits connus
# Comparer les hachages des binaires système avec une référence fiable
find /mnt/evidence/usr/bin/ /mnt/evidence/usr/sbin/ /mnt/evidence/bin/ /mnt/evidence/sbin/ \
-type f -executable -exec sha256sum {} \; > /cases/case-2024-001/linux/analysis/binary_hashes.txt
# Vérifier les binaires SUID/SGID (élévation de privilèges potentielle)
find /mnt/evidence/ -perm -4000 -type f 2>/dev/null > /cases/case-2024-001/linux/analysis/suid_files.txt
find /mnt/evidence/ -perm -2000 -type f 2>/dev/null > /cases/case-2024-001/linux/analysis/sgid_files.txt
# Vérifier les fichiers suspects dans /tmp et /dev/shm
find /mnt/evidence/tmp/ /mnt/evidence/dev/shm/ -type f 2>/dev/null \
-exec file {} \; > /cases/case-2024-001/linux/analysis/tmp_files.txt
# Vérifier les fichiers et répertoires cachés
find /mnt/evidence/ -name ".*" -not -path "*/\\." -type f 2>/dev/null | \
head -100 > /cases/case-2024-001/linux/analysis/hidden_files.txt
# Vérifier les modules noyau
ls -la /mnt/evidence/lib/modules/$(ls /mnt/evidence/lib/modules/ | head -1)/extra/ 2>/dev/null \
> /cases/case-2024-001/linux/analysis/extra_modules.txt
# Vérifier les modifications de configuration PAM (backdoor d'authentification)
diff /mnt/evidence/etc/pam.d/ /cases/baseline/pam.d/ 2>/dev/null \
> /cases/case-2024-001/linux/analysis/pam_changes.txt
Concepts clés
| Concept | Description |
|---|---|
| /var/log/auth.log | Journal d'authentification principal sur les systèmes Debian/Ubuntu |
| /var/log/secure | Journal d'authentification principal sur les systèmes RHEL/CentOS |
| wtmp/btmp | Journaux binaires enregistrant les sessions de connexion réussies et échouées |
| .bash_history | Fichier d'historique des commandes utilisateur (peut être effacé par les attaquants) |
| crontab | Système de tâches planifiées couramment utilisé pour la persistance |
| authorized_keys | Clés publiques SSH accordant un accès sans mot de passe à un compte |
| Bit SUID | Permission de fichier permettant l'exécution en tant que propriétaire du fichier (vecteur d'élévation de privilèges) |
| LD_PRELOAD | Variable d'environnement chargeant une bibliothèque partagée avant toutes les autres (technique de hooking) |
Outils et systèmes
| Outil | Objectif |
|---|---|
| chkrootkit | Scanner de détection de rootkits pour les systèmes Linux |
| rkhunter | Rootkit Hunter – vérifie la présence de rootkits, backdoors et exploits locaux |
| AIDE | Environnement avancé de détection d'intrusion – moniteur d'intégrité des fichiers |
| auditd | Cadre d'audit Linux pour la surveillance des appels système et des accès aux fichiers |
| last/lastb | Analyser les journaux wtmp/btmp pour l'historique des connexions et des échecs |
| Plaso/log2timeline | Création de super-chronologies incluant les artefacts Linux |
| osquery | Interrogation système basée sur SQL pour une investigation forensique live |
| Velociraptor | Agent de point d'extrémité avec capacités de collecte d'artefacts Linux |
Scénarios courants
Scénario 1 : Brute force SSH suivi d'une compromission Analyser auth.log pour les tentatives SSH échouées suivies d'un succès, identifier l'IP attaquante, vérifier .bash_history pour les commandes post-compromission, examiner authorized_keys pour les clés de backdoor ajoutées, vérifier crontab pour la persistance, examiner les connexions réseau.
Scénario 2 : Compromission de serveur web via une vulnérabilité applicative Examiner les journaux d'accès et d'erreurs du serveur web pour les tentatives d'exploitation, vérifier /tmp et /dev/shm pour les webshells, analyser l'activité de l'utilisateur du serveur web (www-data), vérifier l'élévation de privilèges via les binaires SUID ou les exploits du noyau, examiner les connexions sortantes.
Scénario 3 : Menace interne sur un serveur de base de données Analyser l'historique bash de l'utilisateur suspect pour les commandes de dump de base de données, vérifier la présence de gros fichiers tar/zip dans le répertoire personnel ou /tmp, examiner les commandes scp/rsync pour le transfert de données, vérifier les tâches cron pour l'exfiltration automatisée, examiner les journaux de périphériques USB.
Scénario 4 : Crypto-mineur sur une instance cloud Vérifier les processus à forte utilisation CPU dans /proc (live) ou les fichiers de service systemd, examiner les entrées crontab pour les scripts de redémarrage du mineur, vérifier /tmp pour les binaires de minage, analyser les connexions réseau pour les communications avec les pools de minage, examiner authorized_keys pour l'accès de l'attaquant.
Format de sortie
Résumé forensique Linux :
Système : webserver01 (Ubuntu 22.04 LTS)
Nom d'hôte : webserver01.corp.local
Noyau : 5.15.0-91-generic
Comptes utilisateur :
Total : 25 (3 avec UID 0 - 1 ANOMALIE)
Shells interactifs : 8 utilisateurs
Récemment créé : admin2 (créé le 2024-01-15)
Événements d'authentification :
Connexions SSH réussies : 456
Tentatives SSH échouées : 12 345 (depuis 23 IP uniques)
Exécutions sudo : 89
Mécanismes de persistance trouvés :
Tâches cron : 3 suspectes (reverse shell, redémarrage du mineur)
Services systemd : 1 inconnu (update-checker.service)
Clés SSH : 2 clés non autorisées dans le authorized_keys de root
rc.local : Modifié avec un cradle de téléchargement
Activité suspecte :
- bash_history contient wget vers une URL pastebin
- Binaire SUID /t