/var/mychoot
我在与 相同的文件系统上有一个目录/
,并且我已将程序启动/var/mychroot/prog
为sudo chroot /var/mychroot /prog
,因此该程序以 EUID 0 运行。
如果程序执行chdir("..") 转义技术,然后它就能够逃脱 chroot 并看到里面的一切/
。 (我已经在 Linux 4.18 上验证了这一点。)
我想阻止这样的逃跑。事实上我想防止各种 chroot 转义,但在这个问题中我只对如何chdir("..") 转义技术在现代 Linux 系统上可以防止。为此,我正在寻找替代品chroot(2)系统调用。
我找到了2个解决方案:枢轴根和MS_移动,但它们仅在/var/mychroot
是挂载点时才起作用,因此如果/var/mychroot
是文件系统中的子目录,它们就会失败/
。在这种情况下还有其他解决方案吗?
我想避免使用技术LD_PRELOAD
(因为LD_PRELOAD
不影响静态链接的可执行文件),使用技术跟踪(2)(因为这样我就无法strace
在 chroot 中运行,而且跟踪(2)正确处理非常棘手:进程会崩溃或挂起)和真正的虚拟化(例如 Xen 或 KVM 或 QEMU;因为性能开销和不太灵活的内存配置)。
回顾一下,我需要:
- 的替代方案chroot(2)系统调用,
- root 可以使用它限制以 root 身份运行的进程(EUID 0),
- 到文件系统的子目录
/
, - 这可以防止chdir("..") 转义技术,
- 并且不使用
LD_PRELOAD
或 - 跟踪(2)或者
- 虚拟化(例如 Xen、KVM 或 QEMU),
- 它运行在现代 Linux 系统上,
- 带有和未打补丁的内核。
它存在吗?
答案1
为了防止您提到的特定转义技术,您可以在被锁定后chdir("..")
简单地放弃再次执行的能力。转义技术需要再次调用,因此阻止它足以阻止它工作。chroot(2)
/var/mychroot
chroot()
您可以使用 Linux 功能来做到这一点,只需删除CAP_SYS_CHROOT
所需的功能chroot(2)
即可。
例如:
outside# chroot /var/mychroot
inside# capsh --drop=cap_sys_chroot --
inside# ./escape_chroot
chroot(baz): Operation not permitted
(chroot 内的第二个提示来自于 生成的 shell capsh
。您可以使用 使其运行另一个命令,例如capsh --drop=cap_sys_chroot -- -c 'exec ./escape_chroot'
。)
但更好的技术是只使用pivot_root
,因为它可以防止许多其他可能chroot(2)
无法防止的攻击。
您提到它仅在/var/mychroot
是安装点时才有效,但是您可以通过简单地将其绑定安装到自身中来使其成为安装点。
请注意,您需要创建一个挂载命名空间来用于pivot_root
创建监狱,否则它将尝试更改文件系统中所有进程的根目录,这很可能不是您想要的......
所以整个顺序是:
outside# unshare -m
outside# mount --bind /var/mychroot /var/mychroot
outside# cd /var/mychroot
outside# mkdir old_root
outside# pivot_root . old_root
limbo# exec chroot .
inside# umount /old_root
(同样,这些命令中的许多命令都会生成新的 shell。unshare
这样做,它本身也是如此chroot
。您可以通过将命令作为额外参数传递来解决这些问题。在某些情况下,您可能希望传递sh -c '...'
完整的脚本。)
此时,您位于pivot_root
单独的挂载命名空间中的监狱内,事实上,这/var/mychroot
只是原始根目录(而不是单独的设备或循环设备的挂载)并没有真正阻止其工作,感谢绑定安装到自身中。
运行转义代码,您将看到监狱按预期工作(即使转义代码声明不然):
inside# touch /inside_jail
inside# ./escape_chroot
Exploit seems to work. =)
inside# ls -ld /inside_jail /old_root
-rw-r--r--. 1 0 0 0 Jan 5 23:45 /inside_jail
dr-xr-xr-x. 20 0 0 4096 Jul 5 23:45 /old_root
正如你所看到的,仍在监狱内......利用代码有点天真,并假设只要操作(chroot
,chdir
)成功,就足以逃脱监狱,但事实并非如此。 。
因此,考虑使用这种技术来创建一个监狱,该监狱优于chroot
并且不需要使用 Linux 功能来阻止其中的操作(例如创建额外的chroot
s,这对于您实际尝试在监狱。)
答案2
它们仅在 /var/mychroot 是挂载点时才起作用,因此如果 /var/mychroot 只是 / 文件系统中的子目录,它们就会失败。
您可以将任何目录设为挂载点:mount --rbind /var/mychoot /var/mychoot
。
这里介绍了此步骤以及您需要的其他步骤:
事实上我想阻止各种 chroot 逃逸
将以上内容与用户命名空间结合起来。
或者,seccomp
。mount()
例如,这就是 Docker 防止包含的进程调用的方式。 (当您第二次挂载块设备时,您将获得该文件系统的第二个视图,这或多或少算作一种转义)。复制 Docker 允许的系统调用列表 - root 有很多不同的转义方式。
https://docs.docker.com/engine/security/seccomp/
https://github.com/moby/moby/blob/master/profiles/seccomp/default.json