通过添加功能失去权限?

koa*_*alo 8 namespace unshare

我观察到以下我无法解释的现象。添加CAP_SYS_ADMIN功能后,unshare不再能够写入/proc/self/setgroups.

实际上,写入此文件需要该功能,但这是通过更改用户命名空间来实现的。那么为什么父进程添加功能会阻止写入此文件呢?

me@myhost:~$ unshare -r
root@myhost:~# exit
logout

me@myhost:~$ sudo setcap cap_sys_admin=ep /usr/bin/unshare
me@myhost:~$ unshare -r
unshare: cannot open /proc/self/setgroups: Permission denied

me@myhost:~$ sudo setcap cap_sys_admin= /usr/bin/unshare
me@myhost:~$ unshare -r
root@myhost:~#
Run Code Online (Sandbox Code Playgroud)

顺便说一句:我正在运行内核版本为 4.4 的 Ubuntu 16.04.4 LTS,并且 util-linux(包括unshare)的版本为 2.27.1。

fil*_*den 11

这里发生的事情是您的“取消共享”进程无权写入外部用户命名空间上的setgroups(和uid_maps, gid_maps)文件。

在该命名空间中, 中的伪文件/proc/<PID>将由 root 拥有,并且就好像您的有效 uid 仍然是您自己用户的 uid 一样,您将无权写入这些文件。

您可以通过在后台运行进程(例如sleep)并在setgroups文件运行时检查文件的权限(uid_maps并且gid_maps行为完全相同)轻松地将其可视化。

首先,使用没有附加功能的二进制文件:

$ cp /usr/bin/sleep .
$ ./sleep 10 &
[1] 11209
$ ls -l /proc/11209/setgroups
-rw-r--r--. 1 myuser myuser 0 Jul 31 12:33 /proc/11209/setgroups
[1]+  Done                    ./sleep 10
$
Run Code Online (Sandbox Code Playgroud)

然后,让我们为其添加一些文件功能并查看所有权更改:

$ sudo setcap cap_net_bind_service=ep sleep
$ ./sleep 10 &
[1] 11220
$ ls -l /proc/11220/setgroups 
-rw-r--r--. 1 root root 0 Jul 31 12:34 /proc/11220/setgroups
[1]+  Done                    ./sleep 10
$
Run Code Online (Sandbox Code Playgroud)

文件的所有权/proc/<PID>由 Linux 内核中的“可转储”标志控制,该标志用于防止信息从特权进程泄露给非特权用户。

并且考虑到您正在unshare使用附加功能运行但仍然使用非 root有效uid,因此通过操作系统的正常访问控制阻止了对这些由 root 拥有的伪文件的写访问。


您可以使用prctl(2)系统调用的PR_GET_DUMPABLE命令检查“dumpable”标志的值。

PR_SET_DUMPABLE您的描述中,您还会发现:

通常,此标志设置为 1。但是/proc/sys/fs/suid_dumpable,在以下情况下,它会重置为文件中包含的当前值(默认值为 0):

[...]

  • 进程执行 ( execve(2)) 一个具有文件能力的程序(请参阅capabilities(7)),但前提是获得的允许能力超过了进程已经允许的能力。

这正是您的情况,unshare具有文件功能的二进制文件。

有趣的是,使用 root 拥有的 setuid 二进制文件unshare不会遇到这个确切的问题。是的,它将清除“可转储”标志,并且其中的文件/proc/<PID>将由 root 拥有。但是考虑到在运行 setuid 二进制文件时您的有效 uid也是root,将允许访问。

在这种情况下,您最终会遇到另一个问题,这与unshare的逻辑无法处理该特定设置有关(可能与有效 uid 和实际 uid 不匹配有关):

$ cp /usr/bin/unshare .
$ sudo setcap -r unshare
$ sudo chown root:root unshare
$ sudo chmod 4711 unshare
$ ./unshare -r
-bash: cannot set uid to 65534: effective uid 0: Invalid argument
-bash-4.4$ 
Run Code Online (Sandbox Code Playgroud)

另请注意,“可转储”标志的清除是通过运行设置了文件功能的二进制文件触发的。如果您以不同的方式获得额外的功能,您可能不会遇到这个问题。例如,使用“环境”功能是在命名空间之外获得额外功能的好方法,同时在取消共享到新用户命名空间时仍然不会遇到问题。

(不幸的是,目前还没有很多围绕环境功能的工具。libcap仅在最新的 git 中提供支持,过去版本 2.25,这是目前大多数发行版中提供的版本。capsh相当低级,因此获取它并不容易也可以。有关使用最新的添加环境功能的详细信息,请参阅此处capsh。我也尝试过,systemd-run但也无法真正设法在那里设置环境功能。无论如何,如果您确实需要功能,非- root 用户和用户命名空间在一起!)


归档时间:

查看次数:

1286 次

最近记录:

7 年,1 月 前