Domanda

Come si può scoprire di essere in una prigione chroot senza privilegi di root?Supponiamo un sistema BSD o Linux standard.La cosa migliore che mi è venuta in mente è stata guardare il valore dell'inode per "/" e considerare se è ragionevolmente basso, ma vorrei un metodo più accurato per il rilevamento.

[edit 20080916 142430 EST] Guardare semplicemente il filesystem non è sufficiente, poiché non è difficile duplicare cose come /boot e /dev per ingannare l'utente imprigionato.

[edit 20080916 142950 EST] Per i sistemi Linux, è ragionevole verificare la presenza di valori imprevisti all'interno di /proc, ma che dire dei sistemi che non supportano /proc in primo luogo?

È stato utile?

Soluzione

L'inode per / sarà sempre 2 se è la directory root di un filesystem, ma potresti essere sottoposto a chroot all'interno di un filesystem completo.Se si tratta solo di chroot (e non di qualche altra virtualizzazione), potresti eseguire mount e confrontare i filesystem montati con quello che vedi.Verificare che ogni punto di montaggio abbia l'inode 2.

Altri suggerimenti

Se non sei in chroot, l'inode per / sarà sempre 2.Puoi verificarlo utilizzando

stat -c %i /

O

ls -id /

Interessante, ma proviamo a trovare il percorso della directory chroot.Chiedi a stat su quale dispositivo/si trova:

stat -c %04D /

Il primo byte è il maggiore del dispositivo e l'ultimo byte è il minore.Ad esempio, 0802 significa maggiore 8, minore 1.Se controlli in /dev, vedrai che questo dispositivo è /dev/sda2.Se sei root puoi creare direttamente il dispositivo corrispondente nel tuo chroot:

mknode /tmp/root_dev b 8 1

Ora troviamo l'inode associato al nostro chroot.debugfs consente di elencare il contenuto dei file utilizzando i numeri di inode.Per esempio, ls -id / restituito 923960:

sudo debugfs /tmp/root_dev -R 'ls <923960>'
 923960  (12) .       915821  (32) ..     5636100  (12) var   
5636319  (12) lib    5636322  (12) usr    5636345  (12) tmp   
5636346  (12) sys    5636347  (12) sbin   5636348  (12) run   
5636349  (12) root   5636350  (12) proc   5636351  (12) mnt   
5636352  (12) home   5636353  (12) dev    5636354  (12) boot   
5636355  (12) bin    5636356  (12) etc    5638152  (16) selinux   
5769366  (12) srv    5769367  (12) opt    5769375  (3832) media 

Informazioni interessanti sono inode di .. iscrizione:915821.Posso chiederne il contenuto:

sudo debugfs /tmp/root_dev -R 'ls <915821>'
915821  (12) .              2  (12) ..    923960  (20) debian-jail   
923961  (4052) other-jail  

Elenco chiamato debian-jail ha l'inode 923960.Quindi l'ultimo componente della mia directory chroot è debian-jail.Vediamo ora la directory principale (inode 2):

sudo debugfs /tmp/root_dev -R 'ls <2>'
      2  (12) .           2  (12) ..          11  (20) lost+found    1046529  (12) home   
 130817  (12) etc    784897  (16) media     3603  (20) initrd.img   
 261633  (12) var    654081  (12) usr     392449  (12) sys            392450  (12) lib   
 784898  (12) root   915715  (12) sbin   1046530  (12) tmp   
1046531  (12) bin    784899  (12) dev     392451  (12) mnt   
 915716  (12) run        12  (12) proc   1046532  (12) boot               13  (16) lib64   
 784945  (12) srv    915821  (12) opt       3604  (3796) vmlinuz 

Elenco chiamato opt ha l'inode 915821 e l'inode 2 è la root del filesystem.Quindi la mia directory chroot è /opt/debian-jail.Sicuro, /dev/sda1 può essere montato su un altro filesystem.È necessario verificarlo (usare lsof o raccogliere direttamente le informazioni /proc).

Su Linux con permessi root, verifica se la directory root del processo init è la tua directory root.Sebbene /proc/1/root è sempre un collegamento simbolico a /, seguirlo porta alla directory root "master" (assumendo che il processo init non sia in chroot, ma questo non viene quasi mai fatto).Se /proc non è montato, puoi scommettere che sei in un chroot.

[ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]
# With ash/bash/ksh/zsh
! [ -x /proc/1/root/. ] || [ /proc/1/root/. -ef / ]

Questo è più preciso di guardando /proc/1/exe perché potrebbe essere diverso al di fuori di un chroot se init è stato aggiornato dall'ultimo avvio o se il chroot si trova sul filesystem root principale e init è strettamente collegato in esso.

Se non hai i permessi di root, puoi guardare /proc/1/mountinfo E /proc/$$/mountinfo (brevemente documentato in filesystems/proc.txt nella documentazione del kernel Linux).Questo file è leggibile da tutti e contiene molte informazioni su ciascun punto di montaggio nella vista del filesystem del processo.I percorsi in quel file sono limitati dal chroot che influenza il processo di lettura, se presente.Se il processo di lettura /proc/1/mountinfo viene eseguito il chroot in un filesystem diverso dalla radice globale (assumendo che la radice di pid 1 sia la radice globale), quindi nessuna voce per / appare in /proc/1/mountinfo.Se il processo di lettura /proc/1/mountinfo viene chroot in una directory sul filesystem root globale, quindi una voce per / appare in /proc/1/mountinfo, ma con un ID di montaggio diverso.Per inciso, il campo radice ($4) indica dove si trova il chroot nel suo filesystem principale.Ancora una volta, questo è specifico per Linux.

[ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]

Prevenire cose del genere è il punto centrale.Se è il tuo codice che dovrebbe essere eseguito nel chroot, imposta un flag all'avvio.Se stai hackerando, hackera:controlla diverse cose comuni in posizioni conosciute, conta i file in /etc, qualcosa in /dev.

Sui sistemi BSD (controllare con uname -a), proc dovrebbe essere sempre presente.Controlla se la coppia dev/inode di /proc/1/exe (usa stat su quel percorso, non seguirà il collegamento simbolico tramite testo ma tramite l'hook sottostante) corrisponde a /sbin/init.

Anche controllare la root per l'inode n. 2 è utile.

Sulla maggior parte degli altri sistemi, un utente root può scoprirlo molto più velocemente tentando il trucco di rottura root di fchdir.Se va da qualche parte sei in una prigione chroot.

Immagino che dipenda dal motivo per cui potresti trovarti in un chroot e se è stato fatto qualche sforzo per mascherarlo.

Controllerei /proc, questi file sono file di informazioni di sistema generati automaticamente.Il kernel li popolerà nel filesystem root, ma è possibile che non esistano nel filesystem chroot.

Se /proc del filesystem root è stato associato a /proc nel chroot, è probabile che ci siano alcune discrepanze tra tali informazioni e l'ambiente chroot.Controlla /proc/mounts per esempio.

Allo stesso modo, controlla /sys.

Se sei entrato nel chroot con schroot, puoi controllare il valore di $debian_chroot.

Volevo le stesse informazioni per una jail in esecuzione su FreeBSD (poiché Ansible non sembra rilevare questo scenario).

Sulla distribuzione FreeNAS di FreeBSD 11, /proc non è montato sull'host, ma è all'interno della jail.Se questo sia vero anche su FreeBSD normale, non lo so per certo, ma procf:Andato ma non dimenticato sembra suggerire che lo sia.In ogni caso, probabilmente non vorrai provare a montarlo solo per rilevare lo stato di prigione e quindi non sono sicuro che possa essere usato come predittore affidabile dell'essere all'interno di una prigione.

Ho anche escluso l'utilizzo di stat on / poiché certamente su FreeNAS a tutte le jail viene assegnato il proprio file system (ad es. un set di dati ZFS) e quindi il / il nodo sull'host e nella prigione hanno entrambi l'inode 4.Mi aspetto che questo sia comune su FreeBSD 11 in generale.

Quindi l'approccio che ho scelto è stato l'utilizzo procstat su pid 0.

[root@host ~]# procstat 0
  PID  PPID  PGID   SID  TSID THR LOGIN    WCHAN     EMUL          COMM        
    0     0     0     0     0 1234 -        swapin    -             kernel      
[root@host ~]# echo $?
0
[root@host ~]# jexec guest tcsh
root@guest:/ # procstat 0
procstat: sysctl(kern.proc): No such process
procstat: procstat_getprocs()
root@guest:/ # echo $?
1

Sto partendo dal presupposto che pid 0 sarà sempre il kernel sull'host e non ci sarà un pid 0 all'interno della prigione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top