如果没有 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。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top