Обнаружение chroot тюрьмы изнутри - PullRequest
18 голосов
/ 16 сентября 2008

Как можно обнаружить нахождение в изолированной тюрьме без прав root? Предположим, стандартная система BSD или Linux. Лучшее, что я придумал, - это посмотреть на значение inode для «/» и определить, достаточно ли оно низкое, но мне нужен более точный метод обнаружения.

[edit 20080916 142430 EST] Недостаточно просто осмотреть файловую систему, поскольку нетрудно дублировать такие вещи, как / boot и / dev, чтобы обмануть заключенного в тюрьму пользователя.

[edit 20080916 142950 EST] Для систем Linux проверка неожиданных значений в / proc является разумной, но как насчет систем, которые не поддерживают / proc в первую очередь?

Ответы [ 8 ]

14 голосов
/ 18 сентября 2008

Индекс для / всегда будет равен 2, если это корневой каталог файловой системы, но вы можете быть привязаны к целой файловой системе. Если это просто chroot (а не какая-то другая виртуализация), вы можете запустить mount и сравнить смонтированные файловые системы с тем, что вы видите. Убедитесь, что у каждой точки монтирования есть индекс 2.

5 голосов
/ 16 июня 2014

Если вы не находитесь в chroot, индекс для / всегда будет равен 2. Вы можете проверить это, используя

stat -c %i /

или

ls -id /

Интересно, но давайте попробуем найти путь к каталогу chroot. Спросите stat на каком устройстве / находится:

stat -c %04D /

Первый байт является основным в устройстве, а байт - второстепенным. Например, 0802, означает основной 8, второстепенный 1. Если вы войдете в / dev, вы увидите, что это устройство / dev / sda2. Если вы root, вы можете напрямую создать соответствующее устройство в вашем chroot:

mknode /tmp/root_dev b 8 1

Теперь давайте найдем инод, связанный с нашим chroot. debugfs позволяет просматривать содержимое файлов, используя номера инодов. Например, ls -id / вернул 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 

Интересная информация - это индекс .. записи: 915821. Я могу спросить ее содержание:

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

Каталог с именем debian-jail имеет индекс 923960. Таким образом, последний компонент моего каталога chroot - debian-jail. Давайте теперь посмотрим на родительский каталог (индекс 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 

Каталог с именем opt имеет индекс 915821, а индекс 2 является корнем файловой системы. Так что мой каталог chroot /opt/debian-jail. Конечно, /dev/sda1 может быть смонтирован в другой файловой системе. Вы должны проверить это (используйте lsof или непосредственно выбирая информацию /proc).

4 голосов
/ 09 ноября 2011

В Linux с правами доступа root проверьте, является ли корневой каталог процесса init вашим корневым каталогом. Хотя /proc/1/root всегда является символической ссылкой на /, следование по нему ведет к корневому каталогу «master» (при условии, что процесс init не является chroot, но это вряд ли когда-либо будет сделано). Если /proc не смонтирован, вы можете поспорить, что находитесь в 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 / ]

Это более точно, чем , глядя на /proc/1/exe, потому что это может отличаться вне chroot, если init был обновлен с момента последней загрузки или если chroot находится в основной корневой файловой системе и init в нем жестко связан.

Если у вас нет прав доступа root, вы можете посмотреть /proc/1/mountinfo и /proc/$$/mountinfo (кратко документировано в filesystems/proc.txt в документации по ядру Linux ). Этот файл доступен для чтения всем и содержит много информации о каждой точке монтирования в представлении процесса файловой системы. Пути в этом файле ограничены тем, что chroot влияет на процесс чтения, если таковой имеется. Если процесс, читающий /proc/1/mountinfo, привязан к файловой системе, отличной от глобального корня (при условии, что корень pid 1 является глобальным корнем), то в /proc/1/mountinfo не появляется запись для /. Если процесс, читающий /proc/1/mountinfo, привязан к каталогу в глобальной корневой файловой системе, то запись для / появляется в /proc/1/mountinfo, но с другим идентификатором монтирования. Кстати, корневое поле ($4) указывает, где находится chroot в его главной файловой системе. Опять же, это специфично для Linux.

[ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]
3 голосов
/ 18 октября 2008

В системах BSD (проверьте с помощью uname -a), всегда должен присутствовать proc. Проверьте, соответствует ли пара dev / inode файла / proc / 1 / exe (используйте stat для этого пути, он не будет следовать по символической ссылке по тексту, а через основной хук), соответствует /sbin/init.

Проверка корня для inode # 2 также хороша.

В большинстве других систем пользователь root может узнать гораздо быстрее, попробовав взломать корень fchdir. Если он куда-нибудь попадет, то вы попали в тюрьму для chroot.

3 голосов
/ 16 сентября 2008

Предотвращение подобных вещей - вот и весь смысл. Если ваш код должен запускаться в chroot, установите его при запуске. Если вы взломали, взломайте: проверьте несколько общих вещей в известных местах, посчитайте файлы в / etc, что-то в / dev.

1 голос
/ 16 сентября 2008

Полагаю, это зависит от того, почему вы находитесь в chroot, и приложили ли вы какие-либо усилия, чтобы замаскировать его.

Я бы проверил / proc, эти файлы автоматически генерируются файлами системной информации. Ядро заполняет их в корневой файловой системе, но возможно, что они не существуют в файловой системе chroot.

Если корневая файловая система / proc была связана с / proc в chroot, то, вероятно, существуют некоторые расхождения между этой информацией и средой chroot. Проверьте / proc / mounts, например.

Аналогично, проверьте /sys.

0 голосов
/ 17 февраля 2018

Я хотел получить ту же информацию для тюрьмы, работающей во FreeBSD (поскольку Ansible, похоже, не обнаруживает этот сценарий).

В дистрибутиве FreeBSD FreeBSD 11, /proc не смонтирован на хосте, но находится в тюрьме. Верно ли это и для обычной FreeBSD, я точно не знаю, но procfs: Gone But Not Forgotten , похоже, предполагает, что это так. В любом случае, вы, вероятно, не захотите пытаться смонтировать его, просто чтобы обнаружить состояние тюрьмы, и поэтому я не уверен, что его можно использовать как надежный предсказатель нахождения в тюрьме.

Я также исключил использование stat на /, поскольку во FreeNAS наверняка все тюрьмы имеют собственную файловую систему (т.е. набор данных ZFS ) и, следовательно, узел / на хосте и у jail у обоих есть индекс 4. Я ожидаю, что это распространено на FreeBSD 11 в целом.

Итак, я остановился на использовании procstat на 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

Здесь я предполагаю, что pid 0 всегда будет ядром на хосте, а pid 0 внутри тюрьмы не будет.

0 голосов
/ 25 июля 2013

Если вы ввели chroot с помощью schroot, вы можете проверить значение $ debian_chroot.

...