Capabilities

出自 ArchWiki
(重定向自 Setcap)

Capabilities (POSIX 1003.1e, capabilities(7)) 提供了对超级用户权限的细粒度控制,从而可以避免使用 root 用户。 鼓励软件开发者使用更小 Capabilities 集合来替代系统二进制文件中强大的 setuid 属性。 许多软件包都使用了 Capabilities,例如 fping 使用了 CAP_NET_RAW。 这使得 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,则会被认为是 bug,因此应报告这些情况,而不是在此处列出。 本质上等同于 root 访问权限 (CAP_SYS_ADMIN) 或轻易允许 root 访问权限 (CAP_DAC_OVERRIDE) 的 Capability 不算作 bug,因为 Arch 不支持任何 MAC/RBAC 系统。

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

其他受益于 Capabilities 的程序

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

Capabilities 后面的 +ep 表示 Capability 集合为effectivepermitted,更多信息可以在 capabilities(7) § File 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)

参见