Lab Spink : rétablissement d’un pipeline de collecte Splunk
Lab : Spink / Splunk — Basic — Hardening, SIEM, SOC Hôte Windows :
EC2AMAZ-4ML8E8Q(10.8.0.100) Indexer Splunk :10.8.0.101Résultat : ✅ pipeline entièrement rétabli, validation obtenue à 80/80
Résumé exécutif
L’incident ne provenait pas d’une seule panne. La chaîne de collecte comportait cinq défaillances simultanées : le service SplunkForwarder était arrêté, son mode de démarrage Windows était Disabled, la destination TCP pointait vers une adresse erronée, le chemin du journal applicatif était incorrect et l’index applicatif contenait une faute de frappe.
Après correction, le forwarder a atteint l’état Running, la cible 10.8.0.101:9997 est devenue joignable et Splunk a reçu les quatre flux attendus dans l’index endpoint.
1. Objectif et chaîne de collecte
L’objectif du scénario était de restaurer toute la chaîne suivante :
Journaux Windows + C:\AppLogs\app.log
│
▼
Splunk Universal Forwarder sur EC2AMAZ-4ML8E8Q
│ TCP 9997
▼
Indexer Splunk 10.8.0.101
│
▼
Index endpoint dans Splunk Web
│
▼
Flag verifier sur http://10.8.0.101:5000/flag
Le fichier inputs.conf définit les sources locales, notamment les journaux Windows et les fichiers surveillés. Le fichier outputs.conf définit le groupe de sortie TCP et les indexers destinataires.
1.1 Rôle des ports dans le lab
Les ports utilisés n’avaient pas tous le même rôle. Il était important de ne pas confondre le port de transport des événements avec le port de validation du challenge.
| Port | Service | Rôle dans le scénario | Vérification |
|---|---|---|---|
9997/TCP |
Réception Splunk | Port vers lequel le Universal Forwarder envoie les journaux à l’indexer (défini dans outputs.conf) |
Test-NetConnection 10.8.0.101 -Port 9997 |
5000/TCP |
Vérificateur du lab | Service HTTP spécifique au challenge, expose /flag — ce n’est pas le port de collecte Splunk |
curl.exe http://10.8.0.101:5000/flag |
8000/TCP |
Splunk Web | Interface Web pour se connecter à Splunk et exécuter les recherches SPL | http://10.8.0.101:8000/ |
8089/TCP |
splunkd / management | Port de gestion de Splunk ; l’erreur 503 initiale indiquait que ce démon n’était pas disponible | Contrôle de 127.0.0.1:8089 |
Le flux complet peut être représenté ainsi :
EC2AMAZ-4ML8E8Q — 10.8.0.100
│
│ Journaux Windows + C:\AppLogs\app.log
▼
Splunk Universal Forwarder
│
│ TCP 9997 : transport des événements
▼
Indexer Splunk — 10.8.0.101
│
├── TCP 8000 : Splunk Web et recherches SPL
├── TCP 8089 : gestion interne de splunkd
└── TCP 5000 : vérificateur du lab et récupération du flag
Ainsi, le test du port 9997 validait le chemin réseau de collecte, tandis que l’appel au port 5000 servait uniquement à demander au vérificateur si toutes les conditions du scénario étaient réunies.
2. État initial observé
Get-Service *Splunk*; Get-ChildItem 'C:\Program Files\SplunkUniversalForwarder\etc\apps' -Directory | Select-Object Name; Test-NetConnection 10.8.0.101 -Port 9997
Sortie pertinente :
Status Name DisplayName
------ ---- -----------
Stopped SplunkForwarder SplunkForwarder
Name : audit_trail
Name : introspection_generator_addon
Name : learned
Name : search
Name : SplunkUniversalForwarder
Name : splunk_httpinput
Name : splunk_ingest_actions
Name : splunk_internal_metrics
ComputerName : 10.8.0.101
RemoteAddress : 10.8.0.101
PingSucceeded : False
TcpTestSucceeded : True
RemotePort : 9997
SourceAddress : 10.8.0.100
InterfaceDescription : TAP-Windows Adapter V9 for OpenVPN Connect
IsAdmin : True
Cette sortie établissait deux faits importants :
- Le forwarder était arrêté.
- Le port TCP 9997 était joignable malgré l’échec ICMP (
PingSucceeded : False).
💡 Point clé : le ping n’était pas un indicateur suffisant de panne réseau ; le test réellement utile pour la collecte Splunk était
TcpTestSucceeded : Truesur le port de réception.
Côté Splunk Web, l’interface affichait une erreur 503 Service unavailable et indiquait que le démon splunkd sur 127.0.0.1:8089 n’était pas accessible — une indisponibilité temporaire du service côté indexer, à distinguer de la connectivité TCP du forwarder vers le port 9997.
3. Analyse de la configuration effective
$sf = 'C:\Program Files\SplunkUniversalForwarder'
$files = Get-ChildItem "$sf\etc" -Recurse -File -Include inputs.conf,outputs.conf,server.conf,props.conf
$files | Select-Object -ExpandProperty FullName
foreach ($f in $files) {
Write-Host "`n===== $($f.FullName) ====="
Get-Content $f.FullName
}
Fichiers locaux importants :
C:\Program Files\SplunkUniversalForwarder\etc\system\local\inputs.conf
C:\Program Files\SplunkUniversalForwarder\etc\system\local\outputs.conf
C:\Program Files\SplunkUniversalForwarder\etc\system\local\server.conf
3.1 Configuration inputs.conf avant correction
[default]
host = secdojo-endpoint
[WinEventLog://System]
disabled = 0
index = endpoint
[WinEventLog://Application]
disabled = 0
index = endpoint
[WinEventLog://Security]
disabled = 0
index = endpoint
[monitor://C:\AppLogs\application.log]
disabled = 0
index = endpont
sourcetype = secdojo:applog
Les trois stanzas WinEventLog étaient correctes. En revanche, la stanza applicative présentait deux erreurs :
| Paramètre | Valeur erronée | Valeur attendue | Conséquence |
|---|---|---|---|
| Chemin surveillé | C:\AppLogs\application.log |
C:\AppLogs\app.log |
Le fichier réel n’était pas surveillé |
| Index | endpont |
endpoint |
Les événements applicatifs n’étaient pas dirigés vers l’index attendu |
3.2 Configuration outputs.conf avant correction
[tcpout]
defaultGroup = primary_indexers
[tcpout:primary_indexers]
server = 176.16.128.151:9997
L’endpoint réel du lab était 10.8.0.101. L’adresse 176.16.128.151 était donc incorrecte. Même si un test TCP vers 10.8.0.101:9997 réussissait, le forwarder n’utilisait pas cette adresse tant que outputs.conf restait configuré sur l’ancienne cible.
4. Identification de la panne de service Windows
Première tentative de démarrage :
Start-Service SplunkForwarder
Start-Service : Service 'SplunkForwarder (SplunkForwarder)' cannot be started
...
FullyQualifiedErrorId : CouldNotStartService,Microsoft.PowerShell.Commands.StartServiceCommand
Après correction des fichiers de configuration, le service refusait encore de démarrer. La commande de diagnostic déterminante :
Get-CimInstance Win32_Service -Filter "Name='SplunkForwarder'" |
Select-Object Name,State,StartMode,StartName,PathName,ExitCode |
Format-List
Name : SplunkForwarder
State : Stopped
StartMode : Disabled
StartName : NT SERVICE\SplunkForwarder
PathName : "C:\Program Files\SplunkUniversalForwarder\bin\splunkd.exe" service
ExitCode : 1077
⚠️ Point critique :
StartMode : Disabled. Le service pouvait être lancé manuellement dans certaines conditions, mais le gestionnaire de services Windows refusait le démarrage normal.
Tentative complémentaire :
& "$sf\bin\splunk.exe" start --accept-license --answer-yes
Checking mgmt port [8089]: open
Checking conf files for problems...
Done
All installed files intact.
All preliminary checks passed.
Starting splunk server daemon (splunkd)...
SplunkForwarder: Stopped
Les avertissements concernant le proxy HTTP, la clé pass4SymmKey et le certificat Splunk par défaut n’étaient pas la cause bloquante de cet incident. Le diagnostic utile restait le mode de démarrage Windows Disabled.
5. Corrections appliquées
Avant modification, des sauvegardes ont été créées :
$sf = 'C:\Program Files\SplunkUniversalForwarder'
$local = "$sf\etc\system\local"
Copy-Item "$local\inputs.conf" "$local\inputs.conf.bak" -Force
Copy-Item "$local\outputs.conf" "$local\outputs.conf.bak" -Force
5.1 Nouveau inputs.conf
@'
[default]
host = secdojo-endpoint
[WinEventLog://System]
disabled = 0
index = endpoint
[WinEventLog://Application]
disabled = 0
index = endpoint
[WinEventLog://Security]
disabled = 0
index = endpoint
[monitor://C:\AppLogs\app.log]
disabled = 0
index = endpoint
sourcetype = secdojo:applog
'@ | Set-Content "$local\inputs.conf" -Encoding ASCII
5.2 Nouveau outputs.conf
@'
[tcpout]
defaultGroup = primary_indexers
[tcpout:primary_indexers]
server = 10.8.0.101:9997
'@ | Set-Content "$local\outputs.conf" -Encoding ASCII
5.3 Vérification avec btool
& "$sf\bin\splunk.exe" btool inputs list --debug
& "$sf\bin\splunk.exe" btool outputs list --debug
Lignes importantes de la sortie btool :
...\etc\system\local\inputs.conf [WinEventLog://Application]
...\etc\system\local\inputs.conf disabled = 0
...\etc\system\local\inputs.conf index = endpoint
...\etc\system\local\inputs.conf [WinEventLog://Security]
...\etc\system\local\inputs.conf disabled = 0
...\etc\system\local\inputs.conf index = endpoint
...\etc\system\local\inputs.conf [WinEventLog://System]
...\etc\system\local\inputs.conf disabled = 0
...\etc\system\local\inputs.conf index = endpoint
...\etc\system\local\outputs.conf [tcpout:primary_indexers]
...\etc\system\local\outputs.conf server = 10.8.0.101:9997
5.4 Réactivation du service Windows
Set-Service -Name SplunkForwarder -StartupType Automatic
Start-Service -Name SplunkForwarder
Start-Sleep 15
WARNING: Waiting for service 'SplunkForwarder (SplunkForwarder)' to start...
WARNING: Waiting for service 'SplunkForwarder (SplunkForwarder)' to start...
Ces avertissements étaient transitoires. Vérification du succès :
Get-CimInstance Win32_Service -Filter "Name='SplunkForwarder'" |
Select-Object Name,State,StartMode,ExitCode |
Format-List
& 'C:\Program Files\SplunkUniversalForwarder\bin\splunk.exe' status
Test-NetConnection 10.8.0.101 -Port 9997
Name : SplunkForwarder
State : Running
StartMode : Auto
ExitCode : 0
SplunkForwarder: Running (pid 3080)
ComputerName : 10.8.0.101
RemoteAddress : 10.8.0.101
RemotePort : 9997
SourceAddress : 10.8.0.100
TcpTestSucceeded : True
Cette sortie prouve que le service était actif, configuré pour démarrer automatiquement et capable d’atteindre le port de réception Splunk.
6. Validation du journal applicatif
Get-Item 'C:\AppLogs\app.log'
Directory: C:\AppLogs
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 08/14/2026 04:35 PM 1193711 app.log
Ajout d’un événement frais :
Add-Content 'C:\AppLogs\app.log' ("SEC_DOJO_RESTORE " + (Get-Date -Format o))
Lors d’une tentative rapprochée, Windows a signalé un verrou temporaire :
Add-Content : The process cannot access the file
'C:\AppLogs\app.log' because it is being used by another process.
FullyQualifiedErrorId : GetContentWriterIOError
ℹ️ Cette erreur était transitoire et compatible avec la lecture active du fichier par le forwarder. Une tentative ultérieure a réussi, et la taille du fichier est passée de
1193711à1193936octets, confirmant l’écriture d’un nouvel événement.
7. Validation dans Splunk
index=endpoint earliest=-30m
| stats count latest(_time) as last by host sourcetype source
| sort - last
La recherche a retourné 374 événements et quatre lignes de flux :
| Hôte | Sourcetype | Source | Nombre observé | Interprétation |
|---|---|---|---|---|
secdojo-endpoint |
WinEventLog:System |
WinEventLog:System |
198 | Journal système Windows reçu |
secdojo-endpoint |
secdojo:applog |
C:\AppLogs\app.log |
10 | Journal applicatif reçu avec le bon chemin et le bon sourcetype |
secdojo-endpoint |
WinEventLog:Application |
WinEventLog:Application |
15 | Journal applicatif Windows reçu |
secdojo-endpoint |
WinEventLog:Security |
WinEventLog:Security |
151 | Journal de sécurité Windows reçu |
La somme des quatre compteurs est bien 198 + 10 + 15 + 151 = 374, ce qui correspond au nombre total affiché par Splunk. Cette concordance confirme que les quatre sources attendues étaient présentes dans l’index endpoint.
Recherche complémentaire pour le flag ou les événements de contrôle :
index=endpoint earliest=-24h ("SECDOJO{" OR "SECDOJO" OR "flag")
| table _time host source sourcetype _raw
| sort - _time
💡 Pourquoi un événement frais était nécessaire : le vérificateur du lab n’attendait pas seulement que le service soit démarré. Il exigeait qu’un nouvel événement provenant de
C:\AppLogs\app.logtraverse toute la chaîne et atteigneindex=endpointavec un timestamp valide. Un événement ancien ou déjà indexé avant la correction n’aurait pas démontré que la chaîne réparée fonctionnait au moment du contrôle.
Le délai d’environ 90 secondes était nécessaire parce que l’ingestion est asynchrone : le forwarder lit le fichier, place l’événement dans ses files internes, l’envoie sur TCP, puis l’indexer le parse et l’indexe.
Après ce délai, la commande suivante a été exécutée contre le service de validation du lab (et non contre le port de collecte Splunk) :
curl.exe http://10.8.0.101:5000/flag
Réponse obtenue :
flag: SECDOJO{3e2a25b276b719f2d995af3ed03b779b}
La capture finale du lab a confirmé :
You have successfully completed Spink
80/80 Points
2 Machines
Basic Difficulty
8. Synthèse des cinq défaillances
| # | Défaillance | Preuve | Correction | État final |
|---|---|---|---|---|
| 1 | Service SplunkForwarder arrêté |
Status : Stopped |
Start-Service SplunkForwarder |
Running |
| 2 | Démarrage Windows désactivé | StartMode : Disabled |
Set-Service ... -StartupType Automatic |
Auto |
| 3 | Mauvaise adresse de sortie | server = 176.16.128.151:9997 |
Remplacement par 10.8.0.101:9997 |
Correcte |
| 4 | Mauvais chemin applicatif | C:\AppLogs\application.log |
Remplacement par C:\AppLogs\app.log |
Correct |
| 5 | Faute de frappe dans l’index | index = endpont |
Remplacement par index = endpoint |
Correct |
9. Procédure reproductible condensée
Pour reproduire proprement le diagnostic sur un autre endpoint Splunk Universal Forwarder Windows :
$sf = 'C:\Program Files\SplunkUniversalForwarder'
$local = "$sf\etc\system\local"
Get-Service SplunkForwarder
Test-NetConnection 10.8.0.101 -Port 9997
Get-CimInstance Win32_Service -Filter "Name='SplunkForwarder'" |
Select-Object Name,State,StartMode,StartName,PathName,ExitCode |
Format-List
& "$sf\bin\splunk.exe" btool inputs list --debug
& "$sf\bin\splunk.exe" btool outputs list --debug
Set-Service -Name SplunkForwarder -StartupType Automatic
Start-Service -Name SplunkForwarder
Start-Sleep 15
& "$sf\bin\splunk.exe" status
Test-NetConnection 10.8.0.101 -Port 9997
Get-Item 'C:\AppLogs\app.log'
Dans Splunk Web, la validation minimale est :
index=endpoint earliest=-30m
| stats count latest(_time) as last by host sourcetype source
| sort - last
La vérification finale du lab :
curl.exe http://10.8.0.101:5000/flag
10. Conclusion
L’incident a été résolu en suivant la chaîne de collecte de bout en bout plutôt qu’en se limitant à l’interface Splunk. Le test réseau a montré que le port 9997 était accessible ; l’analyse des fichiers locaux a ensuite révélé les erreurs de destination, de chemin et d’index ; enfin, l’inspection du service Windows a mis en évidence le mode de démarrage Disabled.
Après correction des cinq défauts et émission d’un événement applicatif frais, Splunk a reçu les journaux Windows et le journal C:\AppLogs\app.log dans l’index endpoint. Le vérificateur a alors délivré le flag et le lab a été validé à 80/80.
Flag final :
SECDOJO{3e2a25b276b719f2d995af3ed03b779b}
Leçons retenues
PingSucceeded : Falsene signifie pas forcément une panne réseau — ICMP peut être filtré alors que le port applicatif reste joignable. Toujours se fier àTcpTestSucceededpour valider un flux de collecte.- Une configuration réseau correcte (port joignable) ne garantit pas qu’elle soit effectivement utilisée :
outputs.confdoit pointer vers la bonne cible pour que le test réseau ait un sens opérationnel. - Le mode de démarrage Windows (
StartMode) d’un service est une cause de panne à vérifier séparément de son état courant (State) — un service peut sembler correctement configuré en apparence tout en étantDisabledau niveau du gestionnaire de services. btoolest l’outil de référence pour valider la configuration effective de Splunk (après fusion de tous les fichiers.conf), plutôt que de se fier à la lecture d’un seul fichier local.- Pour valider une chaîne de bout en bout après correction, il vaut mieux injecter un événement frais avec timestamp que de se fier à des événements déjà présents dans l’index, qui ne prouvent pas que la chaîne réparée fonctionne au moment du contrôle.
Références
- Documentation Splunk — inputs.conf
- Documentation Splunk — outputs.conf
- Cmdlet PowerShell —
Set-Service