Capabilities
Capabilities (POSIX 1003.1e, capabilities(7)) 提供了对超级用户权限的细粒度控制,从而可以避免使用 root 用户。 鼓励软件开发者使用更小 Capabilities 集合来替代系统二进制文件中强大的 setuid 属性。 许多软件包都使用了 Capabilities,例如 fping 使用了 CAP_NET_RAW
。 这使得 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,则会被认为是 bug,因此应报告这些情况,而不是在此处列出。 本质上等同于 root 访问权限 (CAP_SYS_ADMIN
) 或轻易允许 root 访问权限 (CAP_DAC_OVERRIDE
) 的 Capability 不算作 bug,因为 Arch 不支持任何 MAC/RBAC 系统。
其他受益于 Capabilities 的程序
以下软件包没有 setuid 属性的文件,但需要 root 权限才能工作。 通过启用某些 Capabilities,普通用户可以使用该程序,而无需提升权限。
Capabilities 后面的 +ep
表示 Capability 集合为effective 和 permitted,更多信息可以在 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
使用 AmbientCapabilities
和 CapabilityBoundingSet
,可以将 Capabilities 分配给 systemd 单元,这比在二进制文件上设置 Capabilities 安全得多。 请参阅 systemd.exec(5)。