Skip to main content

OvertheWire Walktrought

·2945 words·14 mins
Dunny
Author
Dunny

OverTheWire Bandit : mon parcours et mes notes
#

Après avoir terminé le parcours Bandit proposé par OverTheWire, j’ai décidé de regrouper mes notes dans un article plus propre et plus structuré.

L’objectif de Bandit est d’apprendre progressivement à utiliser Linux, comprendre le fonctionnement du shell et découvrir quelques concepts de sécurité informatique à travers une série de défis de difficulté croissante.

Je ne détaille pas les mots de passe des niveaux afin de préserver l’intérêt pédagogique du parcours.


Niveau 0
#

Objectif
#

Récupérer le mot de passe du niveau suivant.

Réflexion
#

Le fichier contenant le mot de passe est directement présent dans le répertoire personnel. Une simple lecture du fichier suffit.

Solution
#

cat readme

À retenir
#

  • cat permet d’afficher le contenu d’un fichier texte.

Niveau 1
#

Objectif
#

Lire un fichier dont le nom commence par un tiret (-).

Réflexion
#

Sous Linux, un nom commençant par - est généralement interprété comme une option de commande. Il faut donc préciser explicitement qu’il s’agit d’un fichier.

Solution
#

cat ./-

À retenir
#

  • Le préfixe ./ permet de désigner un fichier situé dans le répertoire courant.

  • Cela évite que le nom soit interprété comme une option.


Niveau 2
#

Objectif
#

Lire un fichier contenant des espaces dans son nom.

Réflexion
#

Les espaces ont une signification particulière dans le shell. Il faut soit les échapper, soit entourer le nom du fichier de guillemets.

Solution
#

cat ./--spaces\ in\ this\ filename--

Ou :

cat "./--spaces in this filename--"

À retenir
#

  • Un espace peut être échappé avec \.

  • L’autocomplétion avec la touche Tab simplifie souvent la saisie.


Niveau 3
#

Objectif
#

Trouver un fichier caché.

Réflexion
#

Les fichiers cachés sous Linux commencent par un point (.). La commande ls ne les affiche pas par défaut.

Solution
#

ls -la

Une fois le fichier identifié :

cat <nom_du_fichier>

À retenir
#

  • ls -a affiche les fichiers cachés.

  • ls -la ajoute les permissions, propriétaires et tailles.


Niveau 4
#

Objectif
#

Identifier un fichier lisible parmi plusieurs fichiers.

Réflexion
#

Le dossier contient plusieurs fichiers dont un seul est exploitable. La commande file permet d’identifier leur nature.

Solution
#

file ./*

Une fois le bon fichier trouvé :

cat <fichier>

À retenir
#

  • file détermine le type réel d’un fichier.

  • Très utile lorsqu’une extension est absente ou trompeuse.


Niveau 5
#

Objectif
#

Trouver un fichier répondant à des critères précis de taille.

Réflexion
#

Ma première idée était de parcourir tous les répertoires avec ls puis de filtrer les résultats.

ls -la */* | awk '{print $5, $9}' | grep 1033

Cette approche fonctionne partiellement mais ne prend pas en compte les fichiers cachés.

J’ai découvert que le caractère générique * ignore les fichiers commençant par un point.

Solution
#

Activer temporairement l’inclusion des fichiers cachés :

shopt -s dotglob

Puis relancer la recherche.

À retenir
#

  • Les globes (*) ignorent les fichiers cachés.

  • dotglob modifie ce comportement dans Bash.


Niveau 6
#

Objectif
#

Trouver un fichier spécifique dans l’ensemble du système.

Réflexion
#

Le fichier recherché possède plusieurs caractéristiques :

  • propriétaire spécifique ;

  • groupe spécifique ;

  • taille précise.

La commande find est parfaitement adaptée à ce type de recherche.

Solution
#

find / -size 33c -user bandit7 -group bandit6 2>/dev/null

Explication
#

2>/dev/null

redirige les erreurs vers la « poubelle » du système afin d’éviter d’être submergé par les messages de permission refusée.

À retenir
#

  • find est l’outil de référence pour rechercher des fichiers.

  • 2>/dev/null permet de masquer les erreurs.


Niveau 7
#

Objectif
#

Trouver une ligne particulière dans un gros fichier texte.

Réflexion
#

Le mot de passe se trouve sur la même ligne qu’un mot-clé spécifique.

Solution
#

cat data.txt | grep millionth

Version plus concise :

grep millionth data.txt

À retenir
#

  • grep permet de rechercher du texte dans un fichier.

  • Éviter les pipes inutiles lorsque la commande accepte déjà un fichier en entrée.


Niveau 8
#

Objectif
#

Trouver la seule ligne unique d’un fichier.

Réflexion
#

Toutes les lignes sont dupliquées sauf une.

Solution
#

sort data.txt | uniq -u

À retenir
#

  • uniq nécessite généralement un tri préalable.

  • uniq -u affiche uniquement les lignes uniques.


Niveau 9
#

Objectif
#

Extraire du texte lisible depuis un fichier binaire.

Réflexion
#

Le fichier contient principalement des données non textuelles.

Solution
#

strings data.txt | grep "="

À retenir
#

  • strings extrait les chaînes de caractères imprimables.

  • Très utile lors de l’analyse de binaires.


Niveau 10
#

Objectif
#

Décoder une chaîne encodée en Base64.

Solution
#

base64 -d data.txt

À retenir
#

  • Base64 est un encodage, pas un chiffrement.

  • N’importe qui peut décoder une donnée encodée en Base64.


Niveau 11
#

Objectif
#

Décoder un texte chiffré à l’aide de l’algorithme ROT13.

Analyse
#

ROT13 est un chiffrement par substitution très simple. Chaque lettre est remplacée par celle située 13 positions plus loin dans l’alphabet. Comme l’alphabet contient 26 lettres, appliquer ROT13 une seconde fois permet de retrouver le texte original.

Sous Linux, la commande tr permet de réaliser facilement cette transformation.

Solution
#

cat data.txt | tr 'A-Za-z' 'N-ZA-Mn-za-m'

Ce qu’il faut retenir
#

  • tr permet de transformer ou remplacer des caractères.

  • ROT13 n’est pas un véritable mécanisme de sécurité mais un simple procédé d’obfuscation.


Niveau 12
#

Objectif
#

Retrouver un mot de passe caché dans une succession d’archives compressées.

Analyse
#

Ce niveau est probablement l’un des plus amusants du début du parcours. Le fichier fourni est un hexdump qu’il faut d’abord reconstruire avant de pouvoir l’exploiter.

Une fois le fichier restauré, on découvre une série d’archives imbriquées utilisant différents formats de compression.

Solution
#

Reconstruction du fichier :

xxd -r data.txt > archive

Puis identification et extraction répétée :

file archive

Suivie de :

gunzip
bunzip2
tar -xf

selon le type de fichier rencontré.

Ce qu’il faut retenir
#

  • xxd -r permet de reconstruire un fichier à partir d’un dump hexadécimal.

  • file est indispensable lorsqu’on manipule des archives inconnues.

  • Les formats de compression les plus courants sont gzip, bzip2 et tar.


Niveau 13
#

Objectif
#

Se connecter à l’utilisateur suivant à l’aide d’une clé SSH privée.

Analyse
#

Le niveau introduit l’authentification par clé SSH. Contrairement à une authentification classique par mot de passe, le serveur vérifie ici la possession d’une clé privée.

Une difficulté fréquente concerne les permissions du fichier contenant la clé.

Solution
#

chmod 600 sshkey.private

Puis :

ssh -i sshkey.private bandit14@localhost -p 2220

Ce qu’il faut retenir
#

  • Une clé privée SSH ne doit être accessible qu’à son propriétaire.

  • SSH refuse généralement d’utiliser une clé dont les permissions sont trop permissives.


Niveau 14
#

Objectif
#

Envoyer le mot de passe actuel à un service réseau local.

Analyse
#

Le serveur écoute sur le port 30000 et attend simplement la réception du mot de passe du niveau précédent.

L’outil idéal pour ce type d’interaction est Netcat.

Solution
#

nc localhost 30000

Puis saisir le mot de passe demandé.

Ce qu’il faut retenir
#

  • Netcat est souvent surnommé le “couteau suisse du réseau”.

  • Il permet d’établir rapidement des connexions TCP ou UDP.


Niveau 15
#

Objectif
#

Réaliser la même opération que précédemment mais via SSL/TLS.

Analyse
#

Cette fois, le service distant exige une connexion chiffrée.

Netcat ne gère pas TLS nativement, il faut donc utiliser OpenSSL.

Solution
#

openssl s_client -connect localhost:30001

Puis envoyer le mot de passe demandé.

Ce qu’il faut retenir
#

  • TLS protège les communications réseau contre l’interception.

  • openssl s_client est très pratique pour tester des services sécurisés.


Niveau 16
#

Objectif
#

Identifier le bon service parmi plusieurs ports ouverts.

Analyse
#

La première étape consiste à effectuer une reconnaissance réseau afin d’identifier les ports disponibles.

Un seul d’entre eux renvoie les informations nécessaires pour accéder au niveau suivant.

Solution
#

nmap localhost -p 31000-32000

Une fois le bon port identifié :

openssl s_client -connect localhost:31790

Dans mon cas, j’ai rencontré un problème de buffering avec OpenSSL et j’ai finalement utilisé ncat.

Ce qu’il faut retenir
#

  • L’énumération est souvent la première étape d’une phase d’exploitation.

  • nmap est l’un des outils les plus utilisés pour la reconnaissance réseau.


Niveau 17
#

Objectif
#

Comparer deux fichiers afin d’identifier une différence.

Analyse
#

Deux fichiers sont fournis : un ancien et un nouveau. Le mot de passe correspond à la ligne modifiée.

Solution
#

diff passwords.old passwords.new

Ce qu’il faut retenir
#

  • diff permet de comparer rapidement deux fichiers.

  • Cet outil est omniprésent dans les systèmes de gestion de versions.


Niveau 18
#

Objectif
#

Contourner une configuration Bash modifiée.

Analyse
#

Le fichier .bashrc a été altéré afin d’empêcher l’accès normal au shell.

Plutôt que de corriger la configuration, il est plus simple d’éviter Bash complètement.

Solution
#

ssh bandit18@bandit.labs.overthewire.org -p 2220 "cat readme"

Ou en lançant directement un autre shell.

Ce qu’il faut retenir
#

  • Lorsqu’un environnement est cassé, il est souvent plus efficace de le contourner que de le réparer.

  • SSH permet d’exécuter directement une commande distante.


Niveau 19
#

Objectif
#

Comprendre le fonctionnement d’un exécutable SUID.

Analyse
#

Le programme fourni exécute une commande avec les privilèges d’un autre utilisateur.

Après quelques essais, on constate que l’exécutable accepte une commande en argument et l’exécute avec des permissions plus élevées.

Solution
#

./bandit20-do cat /etc/bandit_pass/bandit20

Ce qu’il faut retenir
#

  • Les binaires SUID s’exécutent avec les privilèges de leur propriétaire.

  • Une mauvaise configuration SUID peut entraîner une élévation de privilèges.


Niveau 20
#

Objectif
#

Mettre en place un serveur d’écoute afin de communiquer avec un programme client.

Analyse
#

Le programme fourni doit contacter un serveur TCP local qui renvoie le mot de passe précédent.

Pour simplifier les manipulations, il est pratique d’utiliser plusieurs terminaux ou une session screen.

Solution
#

Premier terminal :

nc -lvp 1234

Second terminal :

./suconnect 1234

Le programme contacte alors le serveur local, récupère le mot de passe et affiche celui du niveau suivant.

Ce qu’il faut retenir
#

  • Netcat peut être utilisé aussi bien comme client que comme serveur.

  • Les outils de multiplexage comme screen ou tmux deviennent vite indispensables en environnement Linux.


Niveau 21
#

Objectif
#

Comprendre le fonctionnement d’une tâche cron afin de récupérer le mot de passe du niveau suivant.

Analyse
#

Dans le répertoire dédié aux tâches planifiées, on trouve un script exécuté automatiquement toutes les minutes.

L’idée est alors d’analyser ce script pour comprendre ce qu’il fait et où il stocke les informations qui nous intéressent.

En examinant son contenu, on découvre qu’il copie le mot de passe dans un fichier temporaire.

Solution
#

Identifier la tâche :

cat /etc/cron.d/cronjob_bandit22

Puis analyser le script appelé :

cat /usr/bin/cronjob_bandit22.sh

Enfin récupérer le contenu du fichier généré :

cat /tmp/<fichier_généré>

Ce qu’il faut retenir
#

  • Les tâches cron sont fréquemment utilisées pour automatiser des opérations système.
  • Une mauvaise gestion des fichiers temporaires peut exposer des informations sensibles.

Niveau 22
#

Objectif
#

Déterminer où un script stocke le mot de passe.

Analyse
#

Cette fois, le script ne stocke pas directement le mot de passe dans un emplacement évident.

Après analyse, on constate qu’il calcule un hash MD5 à partir de la chaîne :

I am user bandit23

Ce hash est ensuite utilisé comme nom de fichier dans /tmp.

Solution
#

Reproduire localement le calcul :

echo "I am user bandit23" | md5sum

Puis consulter le fichier correspondant :

cat /tmp/<hash>

Ce qu’il faut retenir
#

  • Lire le code est souvent plus efficace que de chercher à le contourner.
  • Les fonctions de hachage servent fréquemment à générer des identifiants ou des noms de fichiers.

Niveau 23
#

Objectif
#

Exécuter du code avec les privilèges d’un autre utilisateur.

Analyse
#

Le script cron exécute tous les scripts présents dans un répertoire spécifique.

L’idée consiste donc à déposer notre propre script dans ce répertoire afin qu’il soit exécuté automatiquement avec les privilèges de l’utilisateur cible.

Solution
#

Créer un script :

#!/bin/bash
cat /etc/bandit_pass/bandit24 > /tmp/password

Le rendre exécutable :

chmod +x monscript.sh

Puis le déposer dans le répertoire surveillé.

Après quelques instants :

cat /tmp/password

Ce qu’il faut retenir
#

  • Les répertoires exécutés automatiquement représentent une surface d’attaque importante.
  • Toujours contrôler précisément quels fichiers peuvent être exécutés par une tâche automatisée.

Niveau 24
#

Objectif
#

Retrouver un mot de passe en réalisant une attaque par force brute.

Analyse
#

Le service écoute sur un port TCP et attend deux informations :

  • le mot de passe actuel ;
  • un code PIN à quatre chiffres.

Le nombre de combinaisons possibles étant limité, une attaque exhaustive est envisageable.

Solution
#

Générer toutes les combinaisons :

for i in {0000..9999}
do
    echo "<motdepasse> $i"
done

Puis envoyer le résultat au service :

nc localhost 30002

Une fois le bon code trouvé, le serveur renvoie le mot de passe du niveau suivant.

Ce qu’il faut retenir
#

  • La taille de l’espace de recherche est essentielle lorsqu’on évalue la résistance d’un secret.
  • Un code PIN à quatre chiffres est extrêmement faible.

Niveau 25
#

Objectif
#

Contourner une configuration SSH inhabituelle.

Analyse
#

Ce niveau est probablement l’un des plus déroutants du parcours.

Après inspection du compte cible, on découvre que le shell associé n’est pas un shell classique mais la commande more.

Lors de la connexion SSH, more est lancé automatiquement puis la session se ferme immédiatement.

L’astuce consiste à forcer l’entrée dans le mode interactif de more en réduisant la taille du terminal.

Depuis ce mode, il devient possible de lancer Vim.

Solution
#

Une fois dans more :

v

Puis dans Vim :

:set shell=/bin/bash
:shell

On obtient alors un shell avec les permissions de l’utilisateur.

Ce qu’il faut retenir
#

  • Les programmes interactifs peuvent parfois être utilisés pour sortir d’environnements restreints.
  • Vim possède de nombreuses fonctionnalités permettant d’exécuter des commandes système.

Niveau 26
#

Objectif
#

Exploiter un programme SUID afin d’accéder au mot de passe suivant.

Analyse
#

Le répertoire personnel contient un exécutable appartenant à l’utilisateur suivant.

Après quelques essais, on constate qu’il exécute une commande avec des privilèges plus élevés.

Solution
#

Lister le contenu du répertoire contenant les mots de passe :

./bandit27-do ls /etc/bandit_pass

Puis afficher le mot de passe :

./bandit27-do cat /etc/bandit_pass/bandit27

Ce qu’il faut retenir
#

  • Les binaires SUID sont fréquemment impliqués dans les élévations de privilèges.
  • Comprendre les permissions Linux est indispensable en sécurité offensive.

Niveau 27
#

Objectif
#

Cloner un dépôt Git distant.

Analyse
#

Le niveau introduit Git et les dépôts accessibles via SSH.

Une fois le dépôt cloné, le mot de passe apparaît directement dans son contenu.

Solution
#

git clone ssh://bandit27-git@bandit.labs.overthewire.org:2220/home/bandit27-git/repo

Explorer ensuite les fichiers du dépôt :

cat README

Ce qu’il faut retenir
#

  • Git peut utiliser SSH comme protocole de transport.
  • Un dépôt peut contenir des informations sensibles même lorsqu’elles semblent supprimées.

Niveau 28
#

Objectif
#

Retrouver une information supprimée dans l’historique Git.

Analyse
#

Le dépôt ne contient plus le mot de passe dans sa version actuelle.

En consultant l’historique des commits, on remarque un message indiquant la correction d’une fuite d’information.

Il est alors logique de consulter l’état précédent du dépôt.

Solution
#

Afficher l’historique :

git log

Restaurer ou afficher le commit précédent :

git checkout <commit>

ou

git show <commit>

Ce qu’il faut retenir
#

  • Supprimer un secret d’un dépôt ne suffit pas à le faire disparaître.
  • L’historique Git conserve l’ensemble des versions précédentes.

Niveau 29
#

Objectif
#

Explorer les différentes branches d’un dépôt Git.

Analyse
#

Le contenu de la branche principale ne révèle rien d’intéressant.

Une énumération rapide montre cependant l’existence d’autres branches.

Solution
#

Lister les branches :

git branch -a

Basculer sur la branche de développement :

git checkout dev

Le mot de passe apparaît alors dans le fichier README.

Ce qu’il faut retenir
#

  • Les branches Git représentent des historiques indépendants.
  • Une information supprimée d’une branche peut rester présente dans une autre.

Niveau 30
#

Objectif
#

Explorer les tags Git.

Analyse
#

Contrairement aux branches, les tags servent généralement à marquer une version particulière d’un projet.

Dans ce niveau, le mot de passe est directement stocké dans un tag.

Solution
#

Lister les tags :

git tag

Afficher leur contenu :

git show <tag>

Ce qu’il faut retenir
#

  • Les tags permettent de marquer des points précis dans l’historique Git.
  • Lors d’un audit, il ne faut jamais se limiter à la branche principale.

Niveau 31
#

Objectif
#

Comprendre l’utilité du fichier gitignore

Analyse
#

Un fichier gitignore spécifie des fichiers intentionnellement non suivis que git ignorera lors d’un push du dépôt.

Dans ce niveau tous les fichiers en .txt seront ignorés, il nous faut donc modifier le fichier .gitignore.

Solution
#

Supprimer la ligne correspondant au .txt

vim .gitignore

Créer le fichier key.txt et effectuer le push

echo "May I come in?" > key.txt
git add key.txt
git commit -m key
git push

Ce qu’il faut retenir
#

Le fichier .gitignore nous permet d’ignorer tous les fichiers mentionnés à l’intérieur de celui-ci, lors d’un push.


Niveau 32
#

Objectif
#

Découverte des variables.

Analyse
#

Au sein de Linux il existe plusieurs types de variables : les variables locales (valides dans le Shell actuel), les variables Shell (définies par Shell) et les variables d’environnements (ensembles du système).

Elles sont définies comme suit :

NOM_VAR=valeur_var

Pour afficher la valeur d’une variable :

echo $VAR_NAME

Ou toutes les variables :

printenv

Solution
#

Quand on se connecte au serveur on se rend compte que toutes les commandes qu’on essaye de passer se convertissent en majuscule. Autrement nos commandes sont convertis en variables. Elles ne fonctionnent donc pas. Pour récupérer un Shell normal on va appeler la variable $0 qui correspond au Shell.

$0
cat /etc/bandit\_pass/bandit33