Capabilities
Capabilities (POSIX 1003.1e, capabilities(7)) 提供了对超级用户权限的细粒度控制,允许避免使用 root 用户。鼓励软件开发者使用更精简的 capabilities 集合来替代系统二进制文件对强大的 setuid 属性的使用。许多软件包都使用了 capabilities,例如 CAP_NET_RAW
被用于 fping。这使得普通用户可以运行 fping
(就像使用 setuid 方法一样),同时限制了 fping
中潜在漏洞的安全后果。
实现
Capabilities 在 Linux 上使用扩展属性 (xattr(7)) 在 security 命名空间中实现。所有主要的 Linux 文件系统都支持扩展属性,包括 Ext2、Ext3、Ext4、Btrfs、JFS、XFS 和 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 的其他程序
以下软件包的文件没有 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
使用 AmbientCapabilities
和 CapabilityBoundingSet
,可以将 capabilities 分配给 systemd 单元,这比在二进制文件上设置 capabilities 安全得多。请参阅 systemd.exec(5)。