Catégorie :

Linux

Ce que nous allons voir dans cet article :


Partie théorique

Chroot c’est quoi ?

Chroot est une commande Linux qui permet d’isoler une partie du système du système “classique”.
Par exemple créer un répertoire chrooté spécial dans lequel les utilisateurs qui se sont connectés via SSH vont accéder.

Techniquement la commande chroot va créer un environnement virtuel dans lequel toutes les ressources système seront partagées avec l’hôte.

Chroot va donc changer le répertoire racine par celui qu’on a spécifié. De ce fait, les utilisateurs présents dans cette prison chroot ne pourront pas remonter plus haut dans l’arborescence. Ils ne verront et n’auront accès qu’au répertoire dans lequel ils sont chrooté.

Pourquoi vouloir mettre en place chroot ?

Bref vous l’aurez compris, les utilisations sont multiples en fonction de vos besoins.


Partie pratique

Pour chaque commande qu’on va vouloir utiliser dans la jail (prison chroot) on va devoir copier le binaire en question, ainsi que toutes ses librairies associées.
Il faut ajouter dans la jail le strict minimum pour ce qu’on veut en faire.
Certaines commandes sont déjà présentes comme cd ou pwd.

Pour se faire, nous allons utiliser la commande ldd qui va nous permettre de lister toutes les librairies utilisées par un binaire spécifique.

Par exemple si on veut pouvoir utiliser la commande ls dans notre chroot alors il va falloir copier le binaire ainsi que ses librairies.
Pour localiser l’emplacement du binaire on va utiliser la commande whereis. Voici le résultat de l’exécution sur Ubuntu 18.04.4 LTS :

ls: /bin/ls /usr/share/man/man1/ls.1.gz

Ici ce qui nous intéresse c’est le /bin/ls qui est notre binaire. /usr/share/man/man1/ls.1.gz correspond au manuel d’utilisation de la commande lorsqu’on exécute man ls

On connait désormais l’emplacement de notre binaire. On veut maintenant connaître ses librairies. On va donc exécuter ldd /bin/ls. Voici le résultats (toujours sur Ubuntu 18.04.4 LTS) :

	linux-vdso.so.1 (0x00007ffc79f68000)
	libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f2197714000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2197323000)
	libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f21970b1000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f2196ead000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f2197b5e000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f2196c8e000)

Tous ces résultats peuvent paraître barbares mais ils sont simples à interpréter :

On peut voir cependant que la première et l’avant dernière ligne n’ont pas la même forme que les autres.
Pour faire bref,

Maintenant qu’on possède ces infos il ne nous reste plus qu’à créer notre jail et de copier tout ce qu’il faut dedans pour l’utiliser.

On commence par créer un répertoire à l’emplacement où on veut mettre en place notre chroot :

sudo mkdir -p /home/chroot_jail

On a vu précédemment que la commande ls se situe dans le dossier /bin/ il faut donc également créer ce dossier :

sudo mkdir -p /home/chroot_jail/bin

De même, avec la commande ldd on a vu que les librairies sont situées dans les répertoires /lib/ et /lib64/ :

sudo mkdir -p /home/chroot_jail/lib
sudo mkdir -p /home/chroot_jail/lib64

On peut donc maintenant copier tout ce petit monde dans les dossiers correspondants :

sudo cp /bin/ls /home/chroot_jail/bin/
sudo cp /lib/x86_64-linux-gnu/libselinux.so.1 /home/chroot_jail/lib
sudo cp /lib/x86_64-linux-gnu/libc.so.6 /home/chroot_jail/lib
sudo cp /lib/x86_64-linux-gnu/libpcre.so.3 /home/chroot_jail/lib
sudo cp /lib/x86_64-linux-gnu/libdl.so.2 /home/chroot_jail/lib
sudo cp /lib64/ld-linux-x86-64.so.2 /home/chroot_jail/lib64 #Attention ici c'est bien /lib64/
sudo cp /lib/x86_64-linux-gnu/libpthread.so.0 /home/chroot_jail/lib

Attention ! Il est fort probable que vous n’ayez pas les mêmes noms de librairie que moi. Faîtes attention au copier/coller !

A cette étape on pourrait se dire que tout est bon et qu’on peut partir à l’aventure dans notre chroot. Pas si vite malheureux … Il reste le plus important : le shell

Pour le moment nous n’avons copié que la commande ls donc nous pouvons utiliser QUE celle-ci.
Pour que notre chroot puisse fonctionner il faut au minimum un shell. Dans notre cas on va utiliser /bin/bash.

Vous avez deviné ? Eh oui … il faut refaire la même manipulation …

Il faut savoir que ce que je vous montre ici est vraiment le strict minimum pour faire fonctionner une jail chroot. Pour qu’elle soit plus fonctionnelle il faudrait rajouter les fichiers comme /dev/null, /dev/random, etc …
Attention tout de même il faut toujours garder en tête qu’il faut mettre dans la jail uniquement ce qui est utile pour son bon fonctionnement. On ne va pas mettre Metasploit dedans si on veut juste faire des ping.

Automatiser la tâche

Heureusement pour vous j’ai écrit un petit script bash qui vous permet de facilement créer une chroot à l’endroit souhaité avec les binaires voulus.
Voici le code :

#!/bin/bash

#Usage : ./chroot.sh <path> <commands>
#Example : ./chroot /srv/chroot bash id whoami ls
#Create a chroot at <path> 
#If <commands> is empty there will be only bash created in the chroot
#You must specify at least bash if <commands> isn’t empty
path=$1

mkdir -p $path

#Get every arguments except the first one
for command in $*
do
    if [ $command != $1 ]
    then
        location_full_path=`whereis $command | cut -d ' ' -f2`
        location=`echo $location_full_path | rev | cut -d '/' -f2-20 | rev`
        
        mkdir -p $path$location
        cp $location_full_path $path$location

        i=0

        #Read the command line by line
        ldd $location_full_path | while read -r lib;
        do
            #Skip the first line
            if [ $i -ne 0 ]
            then
                library=`echo $lib | cut -d '/' -f2-20 | cut -d ' ' -f1`
                library_location=/`echo $library | rev | cut -d '/' -f2-20 | rev`

                mkdir -p $path$library_location
                cp /$library $path$library_location

            fi
            ((i=i+1))    #i++

        done
    fi
done

Ce script peut également être retrouvé sur mon Github

Je ne vais pas détailler chaque ligne mais ce qu’il fait c’est qu’il va copier tous les binaires ainsi que les librairies passés en paramètre dans l’emplacement de la chroot (qui sera lui même spécifié en paramètre).

Pour exécuter ce script (avec par exemple comme nom chroot.sh) rien de plus simple :

sudo chmod +x chroot.sh
sudo ./chroot.sh /home/chroot_jail bash ls id

Attention ! Comme précisé plus haut il faut AU MOINS le binaire /bin/bash ou un shell fonctionnel (/bin/sh ou autre)

Si l’exécution du script s’est bien passé alors vous devriez avoir un nouveau dossier à l’emplacement spécifié. Dans l’exemple il se situe dans /home/chroot_jail.
Maintenant que notre jail est créée il suffit d’y “plonger”.

Pour y accéder il faut utiliser la commande chroot.
Elle prend 2 arguments : le chemin vers le nouveau répertoire racine et le programme à exécuter (dans notre cas on veut ouvrir un shell dedans)

Avec l’exemple du dessus on exécute ceci :

sudo chroot /home/chroot_jail bash

On va se retrouver dans notre chroot avec toutes les commandes disponibles que nous avons ajouté.
Dans un répertoire normal, avec un pwd on devrait s’attendre à voir affiché /home/chroot_jail/, sauf qu’ici on nous affiche /.
Comme expliqué dans la partie théorique, chroot va créer un environnement virtuel dans lequel on est à la racine. Impossible donc de remonter plus haut dans l’arborescence.

En théorie il est impossible de s’y échapper. Heureusement pour nous, comme c’est nous-même qui avons lancé la commande chroot il est possible de quitter cette jail avec exit.

Exemple avec SSH

Je peux vous montrer un exemple plus concret avec un utilisateur SSH qui atterrit dans la chroot lors de sa connexion.

On lance notre script (sauf si vous aimez vous faire du mal en le faisant manuellement) pour créer une jail dans /home/chroot_jail/ :

./chroot.sh /home/chroot_jail bash ls cat

On veut que l’utilisateur puisse lister les fichier et lire leur contenu.

On va créer un utilisateur qui va être accessible via SSH et qui se connectera directement dans notre chroot sans possibilité de sortir du périmètre défini par celle-ci :

sudo useradd chroot_user -s "/bin/bash"
sudo passwd chroot_user

Il faut ensuite ajouter les lignes suivantes dans le fichier de configuration de SSH :

sudo nano /etc/ssh/sshd_config
        Match User chroot_user
                    ChrootDirectory /home/chroot_jail

On redémarre le service sshd pour prendre en compte nos changements :

sudo systemctl restart sshd

Et enfin on tente de se connecter en SSH :

ssh chroot_user@localhost

Et hop ! On atterit dans notre chroot !

L’exemple a été fait en local mais évidemment il fonctionne également à distance.

J’espère que cet article a été compréhensible pour vous et qu’il vous aura aidé à mieux comprendre et à utiliser chroot.

Sources

https://www.journaldev.com/38044/chroot-command-in-linux

https://www.howtogeek.com/441534/how-to-use-the-chroot-command-on-linux/

http://doc.ubuntu-fr.org/chroot

https://fr.wikipedia.org/wiki/Chroot

http://www.linux-france.org/article/man-fr/man1/ldd-1.html

https://stackoverflow.com/questions/34428037/how-to-interpret-the-output-of-the-ldd-program