Capabilities

出自 ArchWiki

Capabilities (POSIX 1003.1e, capabilities(7)) 提供了对超级用户权限的细粒度控制,允许避免使用 root 用户。鼓励软件开发者使用更精简的 capabilities 集合来替代系统二进制文件对强大的 setuid 属性的使用。许多软件包都使用了 capabilities,例如 CAP_NET_RAW 被用于 fping。这使得普通用户可以运行 fping(就像使用 setuid 方法一样),同时限制了 fping 中潜在漏洞的安全后果。

实现

Capabilities 在 Linux 上使用扩展属性 (xattr(7)) 在 security 命名空间中实现。所有主要的 Linux 文件系统都支持扩展属性,包括 Ext2、Ext3Ext4BtrfsJFSXFS 和 Reiserfs。以下示例使用 getcap 打印 fping 的 capabilities,然后使用 getfattr 打印相同数据的编码形式

$ getcap /usr/bin/fping
/usr/bin/fping cap_net_raw=ep
$ getfattr --dump --match="^security\\." /usr/bin/fping
# file: usr/bin/fping
security.capability=0sAQAAAgAgAAAAAAAAAAAAAAAAAAA=

有些程序会自动复制扩展属性,而另一些程序则需要特殊的标志。关于这两类程序的示例,请参见扩展属性#保留扩展属性

Capabilities 由 Arch 上的软件包安装脚本设置,例如 fping.install

管理与维护

如果软件包具有过度宽松的 capabilities,则被认为是错误,因此应报告这些情况,而不是在此处列出。本质上等同于 root 访问权限 (CAP_SYS_ADMIN) 或轻易允许 root 访问权限 (CAP_DAC_OVERRIDE) 的 capability 不算作错误,因为 Arch 不支持任何 MAC/RBAC 系统。

警告: 许多 capabilities 允许简单的权限提升。有关示例和说明,请参阅 Brad Spengler 的帖子False Boundaries and Arbitrary Code Execution

受益于 capabilities 的其他程序

以下软件包的文件没有 setuid 属性,但需要 root 权限才能工作。通过启用某些 capabilities,普通用户可以使用该程序而无需权限提升。

capabilities 后面的 +ep 指示 capability 集合为有效允许,更多信息可以在 capabilities(7) § 文件 capabilities 中找到。

程序 命令(以 root 身份运行)
Beep setcap cap_dac_override,cap_sys_tty_config+ep /usr/bin/beep
chvt(1) setcap cap_dac_read_search,cap_sys_tty_config+ep /usr/bin/chvt
iftop(8) setcap cap_net_raw+ep /usr/bin/iftop
mii-tool(8) setcap cap_net_admin+ep /usr/bin/mii-tool
nethogs(8) setcap cap_net_admin,cap_net_raw+ep /usr/bin/nethogs
wavemon(1) setcap cap_net_admin+ep /usr/bin/wavemon

一些打包的二进制文件,例如 mtr(8),已经通过 .install 文件配置了所需的 capabilities。无需如上所述手动添加 capabilities。

实用命令

查找 setuid-root 文件

$ find /usr/bin /usr/lib -perm /4000 -user root

查找 setgid-root 文件

$ find /usr/bin /usr/lib -perm /2000 -group root

以临时 capabilities 运行程序

使用 capsh(1) 可以使用一些特定的 capabilities 运行程序,而无需修改二进制文件的扩展属性。以下示例显示了如何使用 CAP_SYS_PTRACE capability 使用 GDB 附加到进程

$ sudo -E capsh --caps="cap_setpcap,cap_setuid,cap_setgid+ep cap_sys_ptrace+eip" --keep=1 --user="$USER" --addamb="cap_sys_ptrace" --shell=/usr/bin/gdb -- -p <pid>

上面的 -E 提供给 sudo 以传递当前用户的登录环境,例如PATH 变量等等,给子进程。

以下是使用 netcat 绑定到低端口(在本例中为 123)的示例

$ sudo -E capsh --caps="cap_setpcap,cap_setuid,cap_setgid+ep cap_net_bind_service+eip" --keep=1 --user="$USER" --addamb="cap_net_bind_service" --shell=/usr/bin/nc -- -lvtn 123
Listening on 0.0.0.0 123

上面的两个示例实际上只是为了说明目的,因为(在大多数系统上)无论如何您都可以将调试器附加到任何用户拥有的进程,或者以 root 用户身份打开端口 < 1024。但是,使用 capsh 可能会提供一些安全优势,因为 capsh --user 以命名的用户身份运行,并具有所有正常的内核 capabilities(,限制)。

systemd

使用 AmbientCapabilitiesCapabilityBoundingSet,可以将 capabilities 分配给 systemd 单元,这比在二进制文件上设置 capabilities 安全得多。请参阅 systemd.exec(5)

参见