从内部检测 chroot 监狱
如果没有 root 权限,如何检测是否处于 chroot 监狱中? 假设有一个标准的 BSD 或 Linux 系统。 我想出的最好办法是查看“/”的 inode 值并考虑它是否相当低,但我想要一种更准确的检测方法。
[edit 20080916 142430 EST]
仅仅查看文件系统是不够的,因为复制 /boot 和 /dev 等内容来欺骗被监禁的用户并不困难。
[edit 20080916 142950 EST]
对于 Linux 系统,检查 /proc 中的意外值是合理的,但是对于首先不支持 /proc 的系统呢?
How can one detect being in a chroot jail without root privileges? Assume a standard BSD or Linux system. 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.
[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 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
如果 / 是 ext2/ext3/ext4 文件系统的根目录,则 / 的 inode 将始终为 2,但您可能会在完整的文件系统中进行 chroot。 如果只是 chroot(而不是其他虚拟化),您可以运行 mount 并将已安装的文件系统与您所看到的进行比较。 验证每个挂载点都有 inode 2。
The inode for / will always be 2 if it's the root directory of an ext2/ext3/ext4 filesystem, but you may be chrooted inside a complete filesystem. If it's just chroot (and not some other virtualization), you could run mount and compare the mounted filesystems against what you see. Verify that every mount point has inode 2.
在具有root权限的Linux上,测试init进程的根目录是否是您的根目录。 虽然
/proc/1/root
始终是/
的符号链接,但跟随它会导致“master”根目录(假设 init 进程没有 chroot,但这是几乎没有做过)。 如果/proc
没有安装,你可以打赌你处于 chroot 状态。这比 查看
/proc/1/exe 更精确
因为如果init
自上次启动以来已经升级,或者 chroot 位于主根文件系统和init
之外,那么在 chroot 之外可能会有所不同> 是硬链接的。如果没有root权限,可以查看
/proc/1/mountinfo
和/proc/$$/mountinfo
(简要记录在Linux 内核文档中的filesystems/proc.txt
)。 该文件是世界可读的,并且包含有关文件系统进程视图中每个挂载点的大量信息。 该文件中的路径受到影响读取器进程(如果有)的 chroot 的限制。 如果读取/proc/1/mountinfo
的进程被 chroot 到与全局根不同的文件系统中(假设 pid 1 的根是全局根),则没有/
出现在/proc/1/mountinfo
中。 如果读取/proc/1/mountinfo
的进程被 chroot 到全局根文件系统上的目录,则/
条目将出现在/proc/1/ 中mountinfo
,但具有不同的挂载 ID。 顺便说一句,root 字段 ($4
) 指示 chroot 在其主文件系统中的位置。 再次强调,这是 Linux 特有的。On Linux with root permissions, test if the root directory of the init process is your root directory. 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). If/proc
isn't mounted, you can bet you're in a chroot.This is more precise than looking at
/proc/1/exe
because that could be different outside a chroot ifinit
has been upgraded since the last boot or if the chroot is on the main root filesystem andinit
is hard linked in it.If you do not have root permissions, you can look at
/proc/1/mountinfo
and/proc/$$/mountinfo
(briefly documented infilesystems/proc.txt
in the Linux kernel documentation). 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. 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
. 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. Incidentally, the root field ($4
) indicates where the chroot is in its master filesystem. Again, this is specific to Linux.如果您使用 schroot 输入 chroot,则可以检查 $debian_chroot 的值。
If you entered the chroot with schroot, then you can check the value of $debian_chroot.
我想要在 FreeBSD 上运行的监狱的相同信息(因为 Ansible 似乎没有检测到这种情况)。
在 FreeBSD 11 的 FreeNAS 发行版上,
/proc
未安装在主机上,但它位于监狱内。 我不确定在常规 FreeBSD 上是否也是如此,但是 procfs:走了但没有被遗忘似乎表明确实如此。 无论哪种方式,您可能都不想尝试安装它只是为了检测监狱状态,因此我不确定它是否可以用作监狱内的可靠预测器。我还排除了在
/
上使用 stat 的可能性,因为在 FreeNAS 上,所有监狱都拥有自己的文件系统(即 a ZFS 数据集),因此主机上和监狱中的/
节点都有 inode 4。我预计这在 FreeBSD 上很常见一般为11。的方法是在 pid 0 上使用 procstat 。
所以我决定 这里假设 pid 0 将始终是主机上的内核,并且监狱内不会有 pid 0。
I wanted the same information for a jail running on FreeBSD (as Ansible doesn't seem to detect this scenario).
On the FreeNAS distribution of FreeBSD 11,
/proc
is not mounted on the host, but it is within the jail. 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. 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 (i.e. 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.So the approach I settled on was using procstat on pid 0.
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.
在 BSD 系统上(使用 uname -a 检查),proc 应始终存在。 检查 /proc/1/exe 的 dev/inode 对(在该路径上使用 stat,它不会通过文本跟踪符号链接,而是通过底层挂钩)匹配 /sbin/init。
检查根目录中的 inode #2 也是一个不错的选择。
在大多数其他系统上,root 用户可以通过尝试 fchdir root 破解技巧来更快地找到答案。 如果它跑到任何地方,你就会被关进 chroot 监狱。
On BSD systems (check with uname -a), proc should always be present. 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.
Checking the root for inode #2 is also a good one.
On most other systems, a root user can find out much faster by attempting the fchdir root-breaking trick. If it goes anywhere you are in a chroot jail.
我想这取决于你为什么会处于 chroot 状态,以及是否付出了任何努力来掩盖它。
我会检查/proc,这些文件是自动生成的系统信息文件。 内核会将它们填充到根文件系统中,但它们可能不存在于 chroot 文件系统中。
如果根文件系统的 /proc 已绑定到 chroot 中的 /proc,则该信息与 chroot 环境之间可能存在一些差异。 例如检查 /proc/mounts。
同样,检查/sys。
I guess it depends why you might be in a chroot, and whether any effort has gone into disguising it.
I'd check /proc, these files are automatically generated system information files. The kernel will populate these in the root filesystem, but it's possible that they don't exist in the chroot filesystem.
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. Check /proc/mounts for example.
Similrarly, check /sys.
防止这样的事情才是重点。 如果您的代码应该在 chroot 中运行,请让它在启动时设置一个标志。 如果您要进行黑客攻击,请进行黑客攻击:检查已知位置中的几个常见内容,计算 /etc 中的文件数,以及 /dev 中的文件数。
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. If you're hacking, hack: check for several common things in known locations, count the files in /etc, something in /dev.
如果您不在 chroot 中并且根文件系统是 ext2/ext3/ext4,则 / 的 inode 将始终为 2。您可以使用
或
Interresting 进行检查,但让我们尝试查找 chroot 目录的路径。 询问
stat
/ 位于哪个设备上:第一个字节是设备的主要字节,否则字节是次要字节。 例如,0802,表示主设备 8,次设备 1。如果您查看 /dev,您将看到该设备是 /dev/sda2。 如果您是 root,您可以直接在 chroot 中创建相应的设备:
现在,让我们找到与 chroot 关联的 inode。 debugfs 允许使用 inode 编号列出文件内容。 例如,
ls -id /
返回 923960:有趣的信息是
..
条目的索引节点:915821。我可以询问其内容:目录名为
debian-jail< /code> 有 inode 923960。所以我的 chroot 目录的最后一个组件是
debian-jail
。 现在让我们看看父目录(inode 2):名为
opt
的目录具有 inode 915821,inode 2 是文件系统的根目录。 所以我的 chroot 目录是/opt/debian-jail
。 当然,/dev/sda1
可以安装在另一个文件系统上。 您需要检查这一点(使用 lsof 或直接选取信息/proc
)。If you are not in a chroot and the root filesystem is ext2/ext3/ext4, the inode for / will always be 2. You may check that using
or
Interresting, but let's try to find path of chroot directory. Ask to
stat
on which device / is located: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. If you are root you can directly create correspondong device in your chroot:
Now, let's find inode associated to our chroot. debugfs allows list contents of files using inode numbers. For exemple,
ls -id /
returned 923960:Interesting information is inode of
..
entry: 915821. I can ask its content:Directory called
debian-jail
has inode 923960. So last component of my chroot dir isdebian-jail
. Let's see parent directory (inode 2) now:Directory called
opt
has inode 915821 and inode 2 is root of filesystem. So my chroot directory is/opt/debian-jail
. Sure,/dev/sda1
may be mounted on another filesystem. You need to check that (use lsof or directly picking information/proc
).