Sinapsi, the hacklab hacking community
Area Tutorial

MKPReviews->GNU/Linux->chroot-ssh environment [ Cerca ]

chroot-ssh environment
Titolo chroot-ssh environment
Descrizione Creazione di un ambiente chroottato al quale accedervi tramite SSH
Inviata da blackout
Chroot ('ch' da 'change', quindi 'change root') permette di impostare la radice del filesystem visibile da un utente in modo che sia diversa da quella che il kernel usa realmente (ovvero /).
Questo tutorial ha lo scopo di spiegare come e' possibile 'chroottare' un utente che accede ad una macchina tramite SSH 'rinchiudendolo' in una cartella nella quale ci sara' lo stretto indispensabile allo svolgimento del suo compito. Lo scopo del tutorial non e' solo spiegare come fare cio, ma far capire come funziona il tutto, quindi spesso mi soffermero' a spiegare a fondo alcuni punti.

Innanzitutto occorre decidere cosa, l'utente chroottato, debba essere in grado di fare scegliendo una lista di programmi. Non conviene aggiungere roba se non ce ne sia l'effettivo bisogno, perche' piu' programmi e librerie vengono inseriti, maggiore e' la probabilita' che vengano usati fuori dal nostro controllo. Supponiamo di voler installare i seguenti programmi base: bash, cat, cp, ldconfig, ls, mkdir, mv, pwd, rm, uname, id, pwd, vi.

Ora passiamo alla creazione dell'ambiente.
Creiamo una directory per il chroot:

# mkdir /home/chrooted

e al suo interndo creiamo un finto filesystem:

# mkdir /home/chrooted/bin
# mkdir /home/chrooted/dev
# mkdir /home/chrooted/etc
# mkdir /home/chrooted/home
# mkdir /home/chrooted/lib
# mkdir /home/chrooted/usr
# mkdir /home/chrooted/sbin
# mkdir /home/chrooted/usr/bin
# mkdir /home/chrooted/usr/lib

Ora copiamo i programmi:

# cp /bin/bash /home/chrooted/bin
# cp /sbin/ldconfig /home/chrooted/sbin
# 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/binn
# cp /usr/bin/pwd /home/chrooted/usr/bin
# cp /usr/bin/vi /home/chrooted/usr/bin

Quindi pensiamo alle librerie. Per sapere di quali librerie hanno bisogno i nostri programmi possiamo usare il comando ldd. Per conoscere le dipendenze di ls ad esempio basta fare:

# ldd `which ls`
linux-gate.so.1 => (0xffffe000)
librt.so.1 => /lib/librt.so.1 (0xb7f37000)
libc.so.6 => /lib/libc.so.6 (0xb7e1b000)
libpthread.so.0 => /lib/libpthread.so.0 (0xb7dc9000)
/lib/ld-linux.so.2 (0xb7f60000)

E quindi copiare le dipendenze trovate:

# 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

Se abbiamo scelto un bel po di programmi questo procedimento manuale risulta piuttosto lento, per cui converrebbe usare uno scriptino bash del tipo:

PROGRAMMI="/bin/bash /bin/ls /bin/mv /bin/cp /bin/cat /bin/mkdir /bin/pwd /bin/rm /usr/bin/id /usr/bin/pwd /usr/bin/vi /sbin/ldconfig"
for prog in ${PROGRAMMI}; do
cp ${prog} ./${prog}
for lib in `ldd ${prog} 2>/dev/null|awk '{ print $3 }'`; do
mkdir -p ./`dirname ${lib}` || die "errore nella creazione della directory"
if [ -e ${lib} ]; then
cp ${lib} ./${lib} || die "errore nella copia del file"
fi
done
done

Copiati i programmi e le librerie, passiamo ad alcuni files necessari.
Creiamo /etc/ld.so.conf e inseriamo i path delle nostre librerie:

# touch /etc/ld.so.conf
# echo "/lib" > /etc/ld.so.conf
# echo "/usr/lib" >> /etc/ld.so.conf

Creiamo /etc/resolv.conf e inseriamo le informazioni del nostro DNS:

# touch /etc/resolv.conf
# echo "nameserver 192.168.1.1" > /etc/resolv.conf

Creiamo alcuni devices di cui molto spesso abbiamo bisogno e impostiamogli i permessi:

# mkdir dev/pts
# test -b dev/null && mknod dev/null c 1 3
# test -b dev/zero && mknod dev/zero c 1 5
# test -b dev/tty && mknod dev/tty c 5 0
# test -b dev/pts/0 && mknod dev/pts/0 c 136 0
# test -b dev/pts/1 && mknod dev/pts/1 c 136 1
# chmod 666 dev/null dev/zero dev/tty dev/pts/*

Ora creiamo il nostro utente con useradd, supponiamo si chiami 'pluto'. Nella creazione quando andremo ad impostare la directory dell'utente dovremmo inserire una cosa del tipo "/home/chrooted/./home/pluto". Questo perche' quando l'utente si colleghera' usando ssh il nostro server openSSH avra' bisogno di sapere se l'utente va chroottato o meno da qualche parte. Trovando /./ capira' che deve chroottarlo li dentro. Ovviamente OpenSSH da solo non effettua il chroot, qualche riga piu' giu' vedremo come farglielo fare con una semplice patch.

Creato l'utente e' importante anche creare i files /etc/passwd e /etc/group, altrimenti il nostro ambiente non funzionera', inserendo all'interno solo la parte che ci interessa:

egrep "(^root)|(pluto)" /etc/passwd > etc/passwd
egrep "(^root)|(pluto)" /etc/group > etc/group

Vediamo ora come si presenta il nostro falso filesystem:

# tree /home/chrooted
/home/chrooted
|-- bin
| |-- bash
| |-- cat
| |-- cp
| |-- ls
| |-- mkdir
| |-- mv
| |-- pwd
| `-- rm
|-- dev
| |-- null
| |-- pts
| | |-- 0
| | `-- 1
| |-- tty
| `-- zero
|-- etc
| |-- group
| |-- ld.so.conf
| |-- passwd
| `-- resolv.conf
|-- home
| `-- pluto
|-- lib
| |-- ld-linux.so.2
| |-- libc.so.6
| |-- libcrypt.so.1
| |-- libdl.so.2
| |-- libgpm.so.1
| |-- libm.so.6
| |-- libnsl.so.1
| |-- libpthread.so.0
| |-- libresolv.so.2
| |-- librt.so.1
| |-- libtermcap.so.2
| `-- libutil.so.1
|-- sbin
| `-- ldconfig
`-- usr
|-- bin
| |-- id
| |-- pwd
| `-- vi
`-- lib
|-- libcrypto.so.0
`-- libssl.so.0

E' arrivato il momento di configurare OpenSSH per fargli fare il chroot quando pluto si colleghera' al nostro serverino. Per fare cio' e' stata creata un'apposita patch, non dovete fare altro che scaricare i sorgenti di openSSH, scaricare la patch per la corrispondente versione all'indirizzo http://chrootssh.sourceforge.net/download/, applicarla, e compilare OpenSSH:

# tar zxvf openssh-versione.tar.gz
# cd openssh-versione
# patch -p0 < /path_patch
# ./configure --with-md5-passwords
# make
# make install

Il funzionamento della patch e' piuttosto semplice.. andando a vedere il .diff possiamo vedere quello che viene fatto quando un utente cerca di loggarsi.

Nel path della home dell utente viene cercato il famoso "/./"

+ while((new_root = strchr(new_root, '.')) != NULL) {
+ new_root--;
+ if(strncmp(new_root, "/./", 3) == 0) {
+ *new_root = '\0';
+ new_root += 2;

Una volta trovato il "/./" si cerca di effettuare il chroot dell'utente in quel punto del path

+ if(chroot(user_dir) != 0)
+ fatal("Couldn't chroot to user's directory %s", user_dir);
+ pw->pw_dir = new_root;
+ break;
+ }
+
+ new_root += 2;
+ }


Una volta ricompilato OpenSSH con la patch si puo' avviare sshd e testare se tutto e' andato nel verso giusto.

Innanzitutto testiamo l'ambiente con un chroot da locale:

# chroot /home/chrooted
blackout@mastrogentoo / $ ls
bin dev etc home lib sbin usr
blackout@mastrogentoo / $ su
-bash: su: command not found

Ok.. sembra funzionare a dovere

Ora prima di testare chroot con ssh facciamo alcuni aggiustamenti.
Possiamo ad esempio creare il file /etc/profile e impostare la variabile PS1 per rendere la bash piu amichevole (altrimenti all'utente loggato uscira' un prompt del tipo "-bash-3.1$").
Oppure, cosa molto carina, possiamo ridefinirci il comando uname per far comparire quello che vogliamo noi quando verra' richiamato. Scriviamo il nostro uname facendogli accettare i parametri -a, -n e -r :

#include < stdio.h >
int main(int argc, char **argv)
{
int c;
if (argc==1) printf("SapientinOS\n");
else
{
while ((c=getopt(argc,argv,"ahnr")) != -1)
{
switch ( c )
{
case 'a': printf("SapientinOS v.1.0\n"); break;
case 'h': printf("Usage: uname [-a -h -n -r]\n");
printf("-a: print all information\n");
printf("-n: print the network node hostname\n");
printf("-r: print the kernel release\n"); break;
case 'n': printf("chrooted\n"); break;
case 'r': printf("v.1.0\n");
}
}
}
}

Compiliamolo:

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

Ora copiamolo nel nostro falso filesystem:

# cp uname /home/chrooted/bin/

Ora possiamo finalmente testare tutto..

blackout@mastrogentoo ~ $ ssh pluto@localhost
Password:

pluto@SapientinOS ~ > uname -a
SapientinOS v.1.0
pluto@SapientinOS ~ >

Tutto funziona, e spero di essere stato abbastanza chiaro e comp[leto nell' illustrare il funzionamento di tutto.
Happy hacking a tutti.. bye blackout
Giudizio Voti: 1 - Media: 4

Inserisci un commento Vota
Commenti

Statistiche
Abbiamo 10 Tutorial nel nostro database
La pił vista: DNS Spoofing (video)
La pił votata: Coding a smurf

Utenti totali presenti nella sezione Tutorial: 0 (0 Utenti Registrati 0 Visitatori e 0 Utenti Anonimi)
Gli utenti visibili sono:


MKPReviews ©2004-2005 All rights reserved
 


Sinapsi, the HackLab Creative Commons - powered by MKPortal 1.1 fixed
Pagina generata in 0.52313 secondi con 20 query