Обнаружение chroot jail изнутри

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

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

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

См. Также Как мне узнать, что я использую chroot?

Gilles 'SO- stop being evil' 09.11.2011 16:28

Не полностью переносимый (и работает только как suid), но в системах на базе Debian по умолчанию установлен ischroot. См .: manpages.debian.org/jessie/debianutils/ischroot.1.en.html

thom_nic 10.01.2018 18:22
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
20
2
14 479
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

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

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

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

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

Аналогичным образом проверьте / sys.

Хотя связать / proc легко, несоответствия в этих данных было бы сложно замаскировать. Ответ принят.

Topaz 16.09.2008 22:27

На самом деле, поцарапайте это - как насчет систем, отличных от Linux, у которых нет / proc и друзей для начала?

Topaz 16.09.2008 22:29

В вопросе говорится о стандартной системе Linux или BSD. Насколько мне известно, оба имеют / proc.

SpoonMeiser 16.09.2008 22:32
Ответ принят как подходящий

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

Из любопытства, что получает индекс 1?

Topaz 23.09.2008 00:48

плохие блоки (исторические / устаревшие)

user10392 25.09.2008 01:11

В linux / sys и / proc оба являются индексными дескрипторами == 1. devtmpfs являются индексными дескрипторами == 3. Классный трюк, но надежен только в «реальных» файловых системах.

SpamapS 01.02.2011 00:04

Это верно не для каждой файловой системы. В XFS, например, корень имеет индекс 128.

caf 22.02.2011 07:27

IOW, root_inode=$(stat -c %i /); if [ $root_inode -ne 2 -a $root_inode -ne 128 ]; ...

l0b0 03.03.2011 19:22

@Topaz индекс 1 представляет точку монтирования, которая используется в данный момент (что-то смонтировано). Я заметил, что это не относится к devtmpfs.

jankes 29.05.2012 16:40

@SpamapS Неправда о devtmpfs в файловой системе Arch Linux ext4. ls -di /dev показывает 1025.

zeekvfu 07.11.2013 08:17

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

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

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

+1 .. устройство + индексный дескриптор / proc / 1 / root или / proc / 1 / exe - вот как несколько программ в Debian и Ubuntu определяют, запускаются ли они в chroot.

SpamapS 01.02.2011 13:09

Если /sbin/init жестко привязан к среде chroot, он будет иметь тот же dev / inode, что и запущенный: ложно-отрицательный. Если /sbin/init был обновлен после загрузки системы, он будет иметь другой dev / inode даже в реальном корне: ложное срабатывание.

caf 22.02.2011 07:32

Ложноотрицательный результат здесь требует, чтобы корневой индексный дескриптор не был 2. Ложноположительный результат очень редок.

Joshua 22.02.2011 23:51

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

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

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

Если вы не находитесь в 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

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

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

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

Я также исключил использование stat на /, поскольку, конечно же, на FreeNAS все тюрьмы имеют свою собственную файловую систему (например, набор данных ZFS), и поэтому узел / на хосте и в тюрьме имеет индекс 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.

Другие вопросы по теме