GNU/Linux hardening: chroot environment

Chroot ci permette di "imprigionare" un utente in una radice diversa da quella che il kernel usa realmente (/).
Ciò che andremo a realizzare in questo tutorial è la creazione di un environment chroot per SSH mediante il quale potremo, appunto, “rinchiudere” gli utenti in un'unica cartella nella quale destinarvi lo stretto indispensabile.

Definiamo in primo luogo una serie di domande che ci consentiranno di svolgere più facilmente il nostro lavoro:
1. Cosa vogliamo consentire all'utente ?
2. A chi è destinata la shell ?
3. Quanti utenti dovrà contenere l'ambiente chroot ?
4. Che genere di restrizioni vogliamo applicare ?


Rispondere correttamente a queste quattro domande consente di eliminare qualsiasi forma di lavoro inutile permettendo di focalizzare la nostra attenzione ai reali bisogni dell'utente.
Partiamo col dare un'immagine (puramente soggettiva) di ciò che dovrà contenere la nostra cartella ove creeremo l'env. chroot:

1. elenco software essenziale da installare:
bash
cat
cp
ls
mkdir
mv
pwd
rm
uname


2. elenco software opzionale da installare:
gcc
id
perl
pwd
vi
wget


Definito ciò che l'environment dovrà contenere iniziamo a lavorare.
Per far si che ssh funzioni in ambiente chroot dovremo ricorrere alla patch offerta da http://chrootssh.sourceforge.net/download/ scarichiamo quella per la nostra versione di ssh (o in alternativa usuiamo un pacchetto già patchato del tipo openssh-3.9p1-chroot.tar.gz).
Se si è optato per la patch (in formato .diff) scarichiamo i sorgenti di openssh per la versione di patch scaricata, applichiamola ed installiamo openssh patchato:
$ wget ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-versione.tar.gz
$ tar zxvf openssh-versione.tar.gz
$ patch -p0 < /patch/scaricata
$ ./configure --with-md5-passwords
$ make
# make install


Oppure, qualora volessimo la versione già patchata:
$ wget http://chrootssh.sourceforge.net/download/openssh-versione-chroot.tar.gz
$ tar zxvf openssh-versione-chroot.tar.gz
$ ./configure --with-md5-passwords
$ make
# make install


Riavviamo sshd:
# /etc/rc.d/rc.sshd stop
# /etc/rc.d/rc.sshd start


Arrivati a questo punto non ci resta altro da fare se non creare l'ambiente chroot vero e proprio.
Creiamo una directory per chroot:
# mkdir /home/chrooted

All'interndo della stessa creeremo un finto filesystem:
# mkdir /home/chrooted/bin
# mkdir /home/chrooted/usr
# mkdir /home/chrooted/usr/bin
# mkdir /home/chrooted/usr/lib
# mkdir /home/chrooted/lib
# mkdir /home/chrooted/sbin
# mkdir /home/chrooted/etc
# mkdir /home/chrooted/home


Ora procediamo con la copia del software necessario:
# cp /bin/bash /home/chrooted/bin
# cp /bin/ls /home/chrooted/bin
# cp /bin/mv /home/chrooted/bin
# cp /bin/cp /home/chrooted/bin
# cp /bin/cat /home/chrooted/bin
# cp /bin/mkdir /home/chrooted/bin
# cp /bin/pwd /home/chrooted/bin
# cp /bin/rm /home/chrooted/bin

# cp /usr/bin/id /home/chrooted/usr/bin
# cp /usr/bin/gcc /home/chrooted/usr/bin
# cp /usr/bin/perl /home/chrooted/usr/bin
# cp /usr/bin/pwd /home/chrooted/usr/bin
# cp /usr/bin/vi /home/chrooted/usr/bin
# cp /usr/bin/wget /home/chrooted/usr/bin

# cp /sbin/ldconfig /home/chrooted/sbin


Copiato il software penseremo alle librerie:
# ldd /bin/ls
        librt.so.1 => /lib/librt.so.1 (0x47d97000)
        libc.so.6 => /lib/libc.so.6 (0x47da9000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x47ed8000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x47d6d000)

# cp /lib/librt.so.1 home/chrooted/lib
# cp /lib/libc.so.6 home/chrooted/lib
# cp /lib/libpthread.so.0 home/chrooted/lib
# cp /lib/ld-linux.so.2 home/chrooted/lib


Copiate tutte le librerie creeremo /etc/ld.so.conf ed /etc/resolv.conf:
# touch /etc/ld.so.conf
# touch /etc/resolv.conf


All'interno del primo inseriremo il percorso delle librerie (/lib e /usr/lib), nel secondo i dati relativi il nostro nameserver.

Terminati questi passaggi l'albero del nostro filesystem falso dovrà essere simile a:
# tree /home/chrooted
/home/chrooted
|-- bin
|   |-- bash
|   |-- cat
|   |-- cp
|   |-- ls
|   |-- mkdir
|   |-- mv
|   |-- pwd
|   `-- rm
|-- etc
|   |-- ld.so.conf
|   `-- resolv.conf
|-- home
|-- lib
|   |-- ld-linux.so.2
|   |-- libc.so.6
|   |-- libcrypt.so.1
|   |-- libdl.so.2
|   |-- libgpm.so.1
|   |-- libm.so.6
|   |-- libncurses.so.5
|   |-- libnsl.so.1
|   |-- libpthread.so.0
|   |-- libresolv.so.2
|   |-- librt.so.1
|   |-- libtermcap.so.2
|   `-- libutil.so.1
|-- sbin
|   `-- ldconfig
`-- usr
    |-- bin
    |   |-- gcc
    |   |-- id
    |   |-- perl
    |   |-- pwd
    |   |-- vi
    |   `-- wget
    `-- lib
        |-- libcrypto.so.0
        `-- libssl.so.0


Cosa carina sarebbe riscrivere il software uname in maniera tale che l'utente, nell'ambiente chroot, dando il comando uname abbia in risposta un qualcosa di inventato a nostro piacimento.
Scriviamo quindi una versione finta di uname che accetti come parametri unicamente -a, -n ed -r:
<--uname.c----------------------------------------CUT HERE---------->
/*
* uname.c
* GNU/Linux hardening and chroot environment
* by mozako
*/
#include <stdio.h>
int
main(argc, argv)
   int argc;
   char **argv;
{
int c;
        if ( argc == 1 ) {
                printf("Linux\n");
        } else {
                while ( (c = getopt(argc,argv,"anrh")) != -1 ) {
                                switch ( c ) {
                                case 'a' : printf("Linux chrooted v.0.1\n");
                                        break;
                                case 'n' : printf("chrooted\n");
                                        break;
                                case 'r' : printf("v.0.1\n");
                                        break;
                                case 'h' :
                                        printf("Usage: uname [-a -n -r -h]\n");
                                        printf("-a: print all information\n");
                                        printf("-n: print the network node hostname\n");
                                        printf("-r: print the kernel release\n");
                                        break;
                        }
                }
        }
}

<--uname.c---------------------------------------/CUT HERE/--------->

$ gcc uname.c -o uname
$ ./uname
Linux
$ ./uname -a
Linux chrooted v.0.1
$ ./uname -n
chrooted
$ ./uname -r
v.0.1
$ ./uname -h
Usage: uname [-a -n -r -h]
-a: print all information
-n: print the network node hostname
-r: print the kernel release


Accertato che il programmino funzioni passiamo alla copia nell'ambiente chroot:
# cp /path/uname_falso /home/chrooted/bin/uname

Et voilà, anche l'uname falso è servito.
Abbiamo concluso con la creazione del “sistema fasullo”, non rimane altro da fare che provarlo:
# chroot /home/chrooted
I have no name!@web:/#

Proviamo qualche comando:
I have no name!@web:/# ls
bin  etc  home  lib  sbin  usr
I have no name!@web:/# uname -a
Linux chrooted v.0.1
I have no name!@web:/# su
bash: su: command not found         :)
I have no name!@web:/# cd home/
I have no name!@web:/home# ldconfig
I have no name!@web:/home# cat /etc/ld.so.conf
/lib

L'ambiente chroot funziona alla perferzione. E' ora che entra in azione la patch chroot di ssh.
Aggiungiamo un utente con il classico comando adduser ed alla richiesta “Home directory [ /home/user ]” inseriamo: /home/chrooted/./user:
# adduser
Login name for new user []: user
...
Home directory [ /home/user ] /home/chrooted/./home/user
...
Home directory...:  /home/chrooted/./home/user
...
Account setup complete.


Aggiungendo, infatti, /./home/user al percorso /home/chrooted si fà capire a SSH che l'env. chroot risiede, appunto, in /home/chrooted e, pertanto, il nuovo utente avrà come directory root /home/chrooted e non la root del sistema.
Proviamo:
mozako@genesis:~$ ssh -l user 192.168.1.102
[email protected]'s password:
-bash-2.05b$ uname -a
Linux chrooted v.0.1
-bash-2.05b$ cd /; ls
bin  etc  home  lib  sbin  usr
-bash-2.05b$ cat /etc/resolv.conf
nameserver 192.168.1.1
L'ambiente SSH chrooted funziona alla grande !
Sarà premura dell'amministratore, capito ormai come usare chroot e ssh, scegliere quali software copiare all'interno del “finto sistema”.
Rimandiamo pertanto l'admin alla lettura delle 4 domande poste come base della nostra trattazione.

Privacy Policy