Introduction
Splunk est le SIEM (Security Information and Event Management) le plus utilisé en entreprise. En tant qu'analyste SOC, vous passerez une grande partie de votre temps à écrire des requêtes SPL pour détecter des menaces.
Ce guide couvre tout ce qu'il faut savoir pour débuter avec Splunk.
Ce que vous allez apprendre :
- Comprendre l'architecture Splunk
- Naviguer dans l'interface
- Écrire des requêtes SPL
- Créer des dashboards et alertes
- Détecter des menaces courantes
1. Architecture Splunk
Composants principaux
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Forwarder │ ──▶ │ Indexer │ ──▶ │ Search Head │
│ (Collecte) │ │ (Stockage) │ │ (Recherche) │
└─────────────┘ └─────────────┘ └─────────────┘
| Composant | Rôle |
|---|---|
| Universal Forwarder | Agent léger installé sur les machines, collecte et envoie les logs |
| Heavy Forwarder | Forwarder avec capacité de parsing et filtrage |
| Indexer | Stocke, indexe et compresse les données |
| Search Head | Interface web pour rechercher et visualiser |
| Deployment Server | Gère la configuration des forwarders |
Concepts clés
| Terme | Description |
|---|---|
| Index | Base de données où sont stockés les logs |
| Source | Chemin du fichier ou input d'origine |
| Sourcetype | Type de données (format du log) |
| Host | Machine d'où proviennent les logs |
| Event | Une entrée de log unique |
| Field | Clé-valeur extraite d'un event |
2. Interface Splunk
Page d'accueil
Accès par défaut : http://localhost:8000
Éléments principaux :
- Search & Reporting : App principale pour les recherches
- Apps : Applications installées (panneau gauche)
- Settings : Configuration, ajout de données
Barre de recherche
┌────────────────────────────────────────────────────────┐
│ 🔍 index=main sourcetype=access_combined status=404 │
└────────────────────────────────────────────────────────┘
│ ⏰ Last 24 hours ▼ │ │ 🔍 Search │ 💾 Save As │
Time Picker : Toujours définir la période de recherche pour optimiser les performances.
3. SPL - Search Processing Language
Syntaxe de base
index=<index_name> <search_terms> | <command1> | <command2>
Exemple :
index=web status=404 | stats count by uri | sort -count
Recherches simples
# Tous les événements d'un index
index=main
# Filtrer par sourcetype
index=main sourcetype=syslog
# Recherche par mot-clé
index=main error
# Recherche par champ
index=main status=200
# Combinaison de filtres
index=web status=404 method=GET
# Exclure des résultats
index=main NOT status=200
# Wildcards
index=main src_ip=192.168.1.*
# Recherche dans une période
index=main earliest=-1h latest=now
Opérateurs logiques
| Opérateur | Exemple |
|---|---|
AND | status=200 AND method=GET |
OR | status=404 OR status=500 |
NOT | NOT status=200 |
() | (status=404 OR status=500) AND src_ip=10.* |
Opérateurs de comparaison
| Opérateur | Description | Exemple |
|---|---|---|
= | Égal | status=200 |
!= | Différent | status!=200 |
> | Supérieur | bytes>1000 |
< | Inférieur | response_time<100 |
>= | Supérieur ou égal | count>=10 |
<= | Inférieur ou égal | count<=5 |
4. Commandes SPL essentielles
Commandes de transformation
stats - Statistiques
# Compter les événements
index=web | stats count
# Compter par champ
index=web | stats count by status
# Multiples statistiques
index=web | stats count, avg(response_time), max(bytes) by uri
# Compter les valeurs uniques
index=web | stats dc(src_ip) as unique_ips
Fonctions stats courantes :
| Fonction | Description |
|---|---|
count | Nombre d'événements |
dc() | Distinct count (valeurs uniques) |
avg() | Moyenne |
sum() | Somme |
min() | Minimum |
max() | Maximum |
values() | Liste des valeurs |
first() | Première valeur |
last() | Dernière valeur |
table - Afficher des colonnes
index=web | table _time, src_ip, uri, status, bytes
top et rare - Valeurs fréquentes/rares
# Top 10 des IPs sources
index=web | top 10 src_ip
# Top avec pourcentage
index=web | top 10 src_ip showperc=true
# Valeurs les plus rares
index=web | rare useragent
timechart - Graphique temporel
# Événements par heure
index=web | timechart span=1h count
# Par statut HTTP
index=web | timechart count by status
# Moyenne du temps de réponse
index=web | timechart avg(response_time)
sort - Trier les résultats
# Tri croissant
index=web | stats count by src_ip | sort count
# Tri décroissant
index=web | stats count by src_ip | sort -count
# Limiter les résultats
index=web | stats count by src_ip | sort -count | head 10
where - Filtre conditionnel
# Filtrer après stats
index=web | stats count by src_ip | where count > 100
# Conditions multiples
index=web | stats count by src_ip, status | where count > 50 AND status=404
dedup - Dédupliquer
# Une seule entrée par IP
index=web | dedup src_ip
# Garder les 2 premières par IP
index=web | dedup 2 src_ip
eval - Créer/modifier des champs
# Créer un nouveau champ
index=web | eval size_kb = bytes/1024
# Conditions
index=web | eval status_type = if(status<400, "OK", "Error")
# Concaténation
index=web | eval full_url = host."/".uri
# Calculs temporels
index=web | eval response_sec = response_time/1000
rex - Extraction regex
# Extraire un pattern
index=main | rex field=_raw "user=(?<username>\w+)"
# Extraire une IP
index=main | rex field=message "(?<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"
rename - Renommer des champs
index=web | stats count by src_ip | rename src_ip as "IP Source", count as "Nombre"
fields - Sélectionner des champs
# Garder certains champs
index=web | fields _time, src_ip, status
# Exclure des champs
index=web | fields - _raw, _bkt
5. Recherches de sécurité
Détection de brute force
# Échecs de connexion Windows (Event ID 4625)
index=windows EventCode=4625
| stats count by src_ip, user
| where count > 10
| sort -count
# Avec timeline
index=windows EventCode=4625
| timechart span=5m count by src_ip
Détection de scan
# Multiples 404 (scan web)
index=web status=404
| stats count, dc(uri) as unique_uris by src_ip
| where count > 50 AND unique_uris > 20
| sort -count
# Scan de ports
index=firewall action=blocked
| stats dc(dest_port) as ports_scanned by src_ip
| where ports_scanned > 100
PowerShell suspect
# Commandes encodées
index=windows sourcetype=WinEventLog:PowerShell
| search CommandLine="*-enc*" OR CommandLine="*-EncodedCommand*"
| table _time, host, user, CommandLine
# Téléchargements
index=windows sourcetype=WinEventLog:PowerShell
| search CommandLine="*Invoke-WebRequest*" OR CommandLine="*wget*" OR CommandLine="*curl*"
| table _time, host, CommandLine
Exfiltration de données
# Gros volumes sortants
index=firewall direction=outbound
| stats sum(bytes) as total_bytes by src_ip, dest_ip
| where total_bytes > 100000000
| eval total_mb = round(total_bytes/1024/1024, 2)
| sort -total_bytes
# Connexions DNS suspectes (tunneling)
index=dns
| stats count, avg(query_length) as avg_len by query
| where avg_len > 50 AND count > 100
Nouveaux services/processus
# Nouveau service Windows (Event ID 7045)
index=windows EventCode=7045
| table _time, host, ServiceName, ImagePath, ServiceType
# Processus suspects
index=windows sourcetype=WinEventLog:Security EventCode=4688
| search NewProcessName="*\\Temp\\*" OR NewProcessName="*\\AppData\\*"
| table _time, host, user, NewProcessName, CommandLine
Connexions C2 potentielles
# Beacons réguliers (connexions à intervalle fixe)
index=firewall direction=outbound
| bin _time span=1m
| stats count by _time, dest_ip
| streamstats count as consecutive by dest_ip
| where consecutive > 60
# Connexions vers IPs externes inhabituelles
index=firewall direction=outbound NOT dest_ip=10.* NOT dest_ip=192.168.* NOT dest_ip=172.16.*
| stats count by dest_ip, dest_port
| where count > 1000
6. Dashboards
Créer un dashboard
- Exécutez une recherche
- Save As → Dashboard Panel
- Choisissez : New Dashboard ou Existing
- Sélectionnez le type de visualisation
Types de visualisations
| Type | Usage |
|---|---|
| Single Value | KPI, compteur |
| Line Chart | Tendances temporelles |
| Bar Chart | Comparaisons |
| Pie Chart | Répartition |
| Table | Données détaillées |
| Map | Géolocalisation |
Exemple de dashboard SOC
┌─────────────────────────────────────────────────────────┐
│ SOC Dashboard │
├─────────────┬─────────────┬─────────────┬───────────────┤
│ Events/Hour │ Failed Auth │ Top Attackers│ Alert Count │
│ 12,453 │ 234 │ 192.168.1.5 │ 18 │
├─────────────┴─────────────┴─────────────┴───────────────┤
│ Events Timeline (Last 24h) │
│ ▁▂▃▄▅▆▇█▇▆▅▄▃▂▁▂▃▄▅▆▇█▇▆▅▄▃▂▁▂▃▄▅▆▇█▇▆▅▄▃▂▁ │
├─────────────────────────────────────────────────────────┤
│ Top 10 Source IPs │
│ 192.168.1.5 ████████████████████ 1,234 │
│ 10.0.0.15 ████████████ 856 │
│ 172.16.1.20 ████████ 534 │
└─────────────────────────────────────────────────────────┘
7. Alertes
Créer une alerte
- Exécutez une recherche
- Save As → Alert
- Configurez :
- Title : Nom de l'alerte
- Schedule : Temps réel ou cron
- Trigger : Condition (ex: results > 0)
- Action : Email, webhook, script
Exemple d'alerte brute force
index=windows EventCode=4625
| stats count by src_ip
| where count > 20
Configuration :
- Schedule : Every 5 minutes
- Trigger : Number of results > 0
- Action : Send email to soc@company.com
8. Bonnes pratiques
Optimisation des recherches
# ❌ Mauvais - Recherche trop large
index=* error
# ✅ Bon - Recherche ciblée
index=web sourcetype=access_combined status=500 earliest=-1h
# ❌ Mauvais - Wildcards au début
index=main src_ip=*.168.1.100
# ✅ Bon - Wildcards à la fin
index=main src_ip=192.168.1.*
# ❌ Mauvais - stats après un gros dataset
index=main | stats count by src_ip
# ✅ Bon - Filtrer d'abord
index=main sourcetype=firewall action=blocked | stats count by src_ip
Conventions de nommage
| Élément | Convention | Exemple |
|---|---|---|
| Saved Search | snake_case descriptif | failed_logins_last_hour |
| Dashboard | Titre clair | SOC - Authentication Monitoring |
| Alert | Préfixe + description | ALERT - Brute Force Detected |
| Macro | Nom court | get_failed_logins |
9. Ressources
Documentation officielle
Cheat Sheets
Practice
Sigma Rules
- Sigma Repository
- Uncoder.io - Convertir Sigma en SPL
