如何在没有root权限的情况下检测到chroot jail?假设标准的BSD或Linux系统。我想出的最好的方法是查看“/”的inode值并考虑它是否相当低,但我想要一种更准确的检测方法。
[edit 20080916 142430 EST]
仅仅查看文件系统是不够的,因为复制诸如/ boot和/ dev之类的东西来欺骗被监禁的用户并不困难。
[edit 20080916 142950 EST]
对于Linux系统,在/ proc中检查意外值是合理的,但是那些首先不支持/ proc的系统呢?
答案 0 :(得分:14)
如果它是文件系统的根目录,则/的inode将始终为2,但您可能在一个完整的文件系统中被chroot。如果它只是chroot(而不是其他一些虚拟化),你可以运行mount并将安装的文件系统与你看到的相比较。验证每个安装点是否具有inode 2。
答案 1 :(得分:5)
如果您不在chroot中,/的inode将始终为2.您可以使用
检查stat -c %i /
或
ls -id /
Interresting,但让我们尝试找到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:915821。我可以问其内容:
sudo debugfs /tmp/root_dev -R 'ls <915821>'
915821 (12) . 2 (12) .. 923960 (20) debian-jail
923961 (4052) other-jail
名为debian-jail
的目录有inode 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
)。
答案 2 :(得分:4)
在具有root权限的Linux上,测试init进程的根目录是否是您的根目录。虽然/proc/1/root
始终是/
的符号链接,但它会导致“主”根目录(假设init进程不是chrooted,但几乎没有完成)。如果没有安装/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 / ]
这比looking at /proc/1/exe
更精确,因为如果自上次启动后init
已升级,或者如果chroot位于主根文件系统init
上,那么在chroot之外可能会有所不同很难相关。
如果您没有root权限,可以查看/proc/1/mountinfo
和/proc/$$/mountinfo
(简要记录在filesystems/proc.txt
in the Linux kernel documentation中)。此文件是世界可读的,并且包含有关文件系统进程视图中每个安装点的大量信息。该文件中的路径受影响读取器进程的chroot限制(如果有)。如果读取/proc/1/mountinfo
的进程被chroot到与全局根不同的文件系统中(假设pid 1的根是全局根),则/
中不会出现/proc/1/mountinfo
的条目。如果读取/proc/1/mountinfo
的进程被chroot到全局根文件系统上的目录,则/
中的/proc/1/mountinfo
条目将出现在$4
中,但具有不同的装入ID。顺便提一下,根字段([ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]
)表示chroot在其主文件系统中的位置。同样,这是Linux特有的。
{{1}}
答案 3 :(得分:3)
防止这样的事情是重点。如果你的代码应该在chroot中运行,那么在启动时设置一个标志。如果你是黑客,黑客:检查已知位置的几个常见事物,计算/ etc中的文件,/ dev中的文件。
答案 4 :(得分:3)
在BSD系统上(使用uname -a检查),proc应始终存在。检查/ proc / 1 / exe的dev / inode对(使用该路径上的stat,它不会通过文本跟踪符号链接而是通过底层钩子)匹配/ sbin / init。
检查inode#2的根也是一个很好的。
在大多数其他系统上,root用户可以通过尝试fchdir root-breaking技巧找到更快的速度。如果它到了你在chroot监狱的任何地方。
答案 5 :(得分:1)
我想这取决于你为什么会在chroot,以及是否有任何努力伪装它。
我检查/ proc,这些文件是自动生成的系统信息文件。内核将在根文件系统中填充它们,但它们可能不存在于chroot文件系统中。
如果根文件系统的/ proc已经绑定到chroot中的/ proc,那么该信息和chroot环境之间可能存在一些差异。例如,检查/ proc / mounts。
同样地,检查/ sys。
答案 6 :(得分:0)
如果您使用schroot进入chroot,那么您可以检查$ debian_chroot的值。
答案 7 :(得分:0)
我想在FreeBSD上运行jail的相同信息(因为Ansible似乎没有检测到这种情况)。
在FreeBSD 11的FreeNAS发行版中,/proc
未安装在主机上,但它位于jail中。这对于常规的FreeBSD是否也是如此,我不确定,但procfs: Gone But Not Forgotten似乎暗示它是。无论哪种方式,你可能都不想尝试安装它只是为了检测监狱状态,因此我不确定它是否可以被用作在监狱内的可靠预测器。
我还排除在/
上使用stat当然在FreeNAS上所有jail都有自己的文件系统(即a ZFS dataset),因此主机上的/
节点和监狱都有inode 4.我希望这在FreeBSD 11中很常见。
所以我确定的方法是在pid 0上使用procstat。
[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将永远是主机上的内核,并且jail中不会有pid。