简体   繁体   English

从内部探测chroot监狱

[英]Detecting a chroot jail from within

How can one detect being in a chroot jail without root privileges? 如何在没有root权限的情况下检测到chroot监狱? Assume a standard BSD or Linux system. 假设标准的BSD或Linux系统。 The best I came up with was to look at the inode value for "/" and to consider whether it is reasonably low, but I would like a more accurate method for detection. 我想出的最好的方法是查看“/”的inode值并考虑它是否相当低,但我想要一种更准确的检测方法。

[edit 20080916 142430 EST] Simply looking around the filesystem isn't sufficient, as it's not difficult to duplicate things like /boot and /dev to fool the jailed user. [edit 20080916 142430 EST]简单地查看文件系统是不够的,因为复制诸如/ boot和/ dev之类的东西来欺骗被监禁的用户并不困难。

[edit 20080916 142950 EST] For Linux systems, checking for unexpected values within /proc is reasonable, but what about systems that don't support /proc in the first place? [edit 20080916 142950 EST]对于Linux系统,在/ proc中检查意外值是合理的,但是那些首先不支持/ proc的系统呢?

The inode for / will always be 2 if it's the root directory of a filesystem, but you may be chrooted inside a complete filesystem. 如果它是文件系统的根目录,则/的inode将始终为2,但您可能在一个完整的文件系统中被chroot。 If it's just chroot (and not some other virtualization), you could run mount and compare the mounted filesystems against what you see. 如果它只是chroot(而不是其他一些虚拟化),你可以运行mount并将安装的文件系统与你看到的相比较。 Verify that every mount point has inode 2. 验证每个安装点是否具有inode 2。

If you are not in a chroot, the inode for / will always be 2. You may check that using 如果您不在chroot中,/的inode将始终为2.您可以检查使用

stat -c %i /

or 要么

ls -id /

Interresting, but let's try to find path of chroot directory. Interresting,但让我们试着找到chroot目录的路径。 Ask to stat on which device / is located: 询问有关哪个设备/所在的stat信息:

stat -c %04D /

First byte is major of device and lest byte is minor. 第一个字节是设备的主要字节,最小字节是次要的。 For example, 0802, means major 8, minor 1. If you check in /dev, you will see this device is /dev/sda2. 例如,0802表示主要8,次要1.如果您检入/ dev,您将看到此设备是/ dev / sda2。 If you are root you can directly create correspondong device in your chroot: 如果您是root用户,可以直接在chroot中创建对应的设备:

mknode /tmp/root_dev b 8 1

Now, let's find inode associated to our chroot. 现在,让我们找到与我们的chroot相关联的inode。 debugfs allows list contents of files using inode numbers. debugfs允许使用inode编号列出文件的内容。 For exemple, ls -id / returned 923960: 例如, 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 

Interesting information is inode of .. entry: 915821. I can ask its content: 有趣的信息是inode of .. entry:915821。我可以问它的内容:

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

Directory called debian-jail has inode 923960. So last component of my chroot dir is debian-jail . 名为debian-jail目录有inode 923960.所以我的chroot dir的最后一个组件是debian-jail Let's see parent directory (inode 2) now: 我们现在看一下父目录(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 

Directory called opt has inode 915821 and inode 2 is root of filesystem. 名为opt目录具有inode 915821,而inode 2是文件系统的根目录。 So my chroot directory is /opt/debian-jail . 所以我的chroot目录是/opt/debian-jail Sure, /dev/sda1 may be mounted on another filesystem. 当然, /dev/sda1可以安装在另一个文件系统上。 You need to check that (use lsof or directly picking information /proc ). 您需要检查(使用lsof或直接选择信息/proc )。

On Linux with root permissions, test if the root directory of the init process is your root directory. 在具有root权限的Linux上,测试init进程的根目录是否是您的根目录。 Although /proc/1/root is always a symbolic link to / , following it leads to the “master” root directory (assuming the init process is not chrooted, but that's hardly ever done). 虽然/proc/1/root始终是一个符号链接到/ ,下面就导致了“主”根目录下(假设init进程不chroot的,但几乎没有做过)。 If /proc isn't mounted, you can bet you're in a 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 / ]

This is more precise than looking at /proc/1/exe because that could be different outside a chroot if init has been upgraded since the last boot or if the chroot is on the main root filesystem and init is hard linked in it. 这比查看/proc/1/exe更精确因为如果init自上次启动以来已经升级,或者如果chroot位于主根文件系统上并且init在其中是硬连接的,那么在chroot之外可能会有所不同。

If you do not have root permissions, you can look at /proc/1/mountinfo and /proc/$$/mountinfo (briefly documented in filesystems/proc.txt in the Linux kernel documentation ). 如果您没有root权限,可以查看/proc/1/mountinfo/proc/$$/mountinfo (简要记录在Linux内核文档的filesystems/proc.txt )。 This file is world-readable and contains a lot of information about each mount point in the process's view of the filesystem. 此文件是世界可读的,并且包含有关文件系统进程视图中每个安装点的大量信息。 The paths in that file are restricted by the chroot affecting the reader process, if any. 该文件中的路径受影响读取器进程的chroot限制(如果有)。 If the process reading /proc/1/mountinfo is chrooted into a filesystem that's different from the global root (assuming pid 1's root is the global root), then no entry for / appears in /proc/1/mountinfo . 如果过程读取/proc/1/mountinfo使用chroot成文件系统这是从全球根不同(假设PID 1的根是全球根),则对于任何条目/出现在/proc/1/mountinfo If the process reading /proc/1/mountinfo is chrooted to a directory on the global root filesystem, then an entry for / appears in /proc/1/mountinfo , but with a different mount id. 如果进程读取/proc/1/mountinfo使用chroot到一个目录对全球根文件系统,那么对于一款入门/将出现在/proc/1/mountinfo ,但有不同的安装ID。 Incidentally, the root field ( $4 ) indicates where the chroot is in its master filesystem. 顺便提一下,根字段( $4 )表示chroot在其主文件系统中的位置。 Again, this is specific to Linux. 同样,这是Linux特有的。

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

On BSD systems (check with uname -a), proc should always be present. 在BSD系统上(使用uname -a检查),应始终存在proc。 Check if the dev/inode pair of /proc/1/exe (use stat on that path, it won't follow the symlink by text but by the underlying hook) matches /sbin/init. 检查/ proc / 1 / exe的dev / inode对(使用该路径上的stat,它不会通过文本跟踪符号链接而是通过底层钩子)匹配/ sbin / init。

Checking the root for inode #2 is also a good one. 检查inode#2的根也是一个很好的根。

On most other systems, a root user can find out much faster by attempting the fchdir root-breaking trick. 在大多数其他系统上,root用户可以通过尝试fchdir root-breaking技巧找到更快的速度。 If it goes anywhere you are in a chroot jail. 如果它在任何地方,你在chroot监狱。

Preventing stuff like that is the whole point. 防止这样的事情是重点。 If it's your code that's supposed to run in the chroot, have it set a flag on startup. 如果你的代码应该在chroot中运行,那么在启动时设置一个标志。 If you're hacking, hack: check for several common things in known locations, count the files in /etc, something in /dev. 如果你是黑客,黑客:检查已知位置的几个常见事物,计算/ etc中的文件,/ dev中的文件。

I guess it depends why you might be in a chroot, and whether any effort has gone into disguising it. 我想这取决于你为什么会在一个chroot,以及是否有任何努力伪装它。

I'd check /proc, these files are automatically generated system information files. 我检查/ proc,这些文件是自动生成的系统信息文件。 The kernel will populate these in the root filesystem, but it's possible that they don't exist in the chroot filesystem. 内核将在根文件系统中填充它们,但它们可能不存在于chroot文件系统中。

If the root filesystem's /proc has been bound to /proc in the chroot, then it is likely that there are some discrepancies between that information and the chroot environment. 如果根文件系统的/ proc已经绑定到chroot中的/ proc,那么该信息和chroot环境之间可能存在一些差异。 Check /proc/mounts for example. 例如,检查/ proc / mounts。

Similrarly, check /sys. 同时,检查/ sys。

如果您使用schroot进入chroot,那么您可以检查$ debian_chroot的值。

I wanted the same information for a jail running on FreeBSD (as Ansible doesn't seem to detect this scenario). 我想在FreeBSD上运行一个jail的相同信息(因为Ansible似乎没有检测到这种情况)。

On the FreeNAS distribution of FreeBSD 11, /proc is not mounted on the host, but it is within the jail. 在FreeBSD 11的FreeNAS发行版中, /proc没有安装在主机上,但它在监狱内。 Whether this is also true on regular FreeBSD I don't know for sure, but procfs: Gone But Not Forgotten seems to suggest it is. 这对于常规FreeBSD是否也是如此我不确定,但是procfs:Gone但Not Forgotten似乎暗示它是。 Either way, you probably wouldn't want to try mounting it just to detect jail status and therefore I'm not certain it can be used as a reliable predictor of being within a jail. 无论哪种方式,你可能不想尝试安装它只是为了检测监狱状态,因此我不确定它是否可以被用作在监狱内的可靠预测器。

I also ruled out using stat on / as certainly on FreeNAS all jails are given their own file system (ie a ZFS dataset ) and therefore the / node on the host and in the jail both have inode 4. I expect this is common on FreeBSD 11 in general. 我还排除了使用stat on /当然在FreeNAS上所有jails都有自己的文件系统(即ZFS数据集 ),因此主机和监狱中的/ node都有inode 4.我希望这在FreeBSD上很常见一般来说是11。

So the approach I settled on was using procstat on pid 0. 所以我确定的方法是在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

I am making an assumption here that pid 0 will always be the kernel on the host, and there won't be a pid 0 inside the jail. 我在这里假设pid 0将永远是主机上的内核,并且jail中不会有pid 0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM