题
如果没有 root 权限,如何检测是否处于 chroot 监狱中?假设有一个标准的 BSD 或 Linux 系统。我想出的最好办法是查看“/”的 inode 值并考虑它是否相当低,但我想要一种更准确的检测方法。
[edit 20080916 142430 EST]
仅仅查看文件系统是不够的,因为复制 /boot 和 /dev 等内容来欺骗被监禁的用户并不困难。
[edit 20080916 142950 EST]
对于 Linux 系统,检查 /proc 中的意外值是合理的,但是对于首先不支持 /proc 的系统呢?
解决方案
如果 / 是文件系统的根目录,则 / 的索引节点将始终为 2,但您可能会在完整的文件系统中进行 chroot。如果只是 chroot(而不是其他虚拟化),您可以运行 mount 并将已安装的文件系统与您所看到的进行比较。验证每个挂载点都有 inode 2。
其他提示
如果您不在 chroot 中,则 / 的 inode 将始终为 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 关联的 inode。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
有趣的信息是 inode of ..
入口: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
. 。现在让我们看看父目录(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
目录名为 opt
有 inode 915821 和 inode 2 是文件系统的根。所以我的chroot目录是 /opt/debian-jail
. 。当然, /dev/sda1
可以安装在另一个文件系统上。您需要检查(使用 lsof 或直接选取信息 /proc
).
在具有root权限的Linux上,测试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
被 chroot 到与全局根不同的文件系统中(假设 pid 1 的根是全局根),则没有条目 /
出现在 /proc/1/mountinfo
. 。如果进程读取 /proc/1/mountinfo
被 chroot 到全局根文件系统上的一个目录,然后是一个条目 /
出现在 /proc/1/mountinfo
, ,但具有不同的安装 ID。顺便说一句,根字段($4
) 指示 chroot 在其主文件系统中的位置。再次强调,这是 Linux 特有的。
[ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]
防止这样的事情才是重点。如果您的代码应该在 chroot 中运行,请让它在启动时设置一个标志。如果你正在黑客攻击,请黑客攻击:检查已知位置中的几个常见内容,计算 /etc 中的文件、/dev 中的文件。
在 BSD 系统上(使用 uname -a 检查),proc 应始终存在。检查 /proc/1/exe 的 dev/inode 对(在该路径上使用 stat,它不会通过文本跟踪符号链接,而是通过底层挂钩)匹配 /sbin/init。
检查根目录中的 inode #2 也是一个不错的选择。
在大多数其他系统上,root 用户可以通过尝试 fchdir root 破解技巧来更快地找到答案。如果它跑到任何地方,你就会被关进 chroot 监狱。
我想这取决于你为什么会处于 chroot 状态,以及是否付出了任何努力来掩盖它。
我会检查/proc,这些文件是自动生成的系统信息文件。内核会将它们填充到根文件系统中,但它们可能不存在于 chroot 文件系统中。
如果根文件系统的 /proc 已绑定到 chroot 中的 /proc,则该信息与 chroot 环境之间可能存在一些差异。例如检查 /proc/mounts。
同样,检查/sys。
如果您使用 schroot 输入 chroot,则可以检查 $debian_chroot 的值。
我想要在 FreeBSD 上运行的监狱的相同信息(因为 Ansible 似乎没有检测到这种情况)。
在 FreeBSD 11 的 FreeNAS 发行版上, /proc
未安装在主机上,但位于监狱内。我不确定在常规 FreeBSD 上是否也是如此,但是 过程:走了但没有被遗忘 似乎表明确实如此。无论哪种方式,您可能都不想尝试安装它只是为了检测监狱状态,因此我不确定它是否可以用作监狱内的可靠预测器。
我也排除了使用 stat on /
当然,在 FreeNAS 上,所有监狱都有自己的文件系统(即 ZFS 数据集),因此 /
主机上的节点和监狱中的节点都有 inode 4。我预计这在 FreeBSD 11 上很常见。
所以我选择的方法是使用 程序统计 在 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。