man 7 capabilities
文档表明 Linux 机器上进程的功能被记录为三个掩码:
- 允许的
- 有效的
- 可继承的
我有一个想法可继承的mask 会发挥作用,但我不清楚为什么似乎需要/用例将允许的功能与有效的功能分开?
是否存在某些允许的功能无效的情况?哪个可以让这个问题的答案变得有趣?
奖金轮
鉴于某些功能无效但又被允许的情况,是什么阻止流程将它们设置为有效?至少在我看来,流氓进程会毫不犹豫地将所有允许的内容设置为有效,并且通常甚至尝试进一步提升特权?
答案1
有效/允许的能力之间的差异类似于 setuid 程序中真实/有效 UID 之间的差异。这个想法并不是要阻止流氓应用程序升级权限(您首先不会授予它们权限,就像您不会设置它们一样),而是允许程序以最小的权限运行,并且仅在必要时升级。这有助于最大限度地减少错误的影响
一个非常人为的示例:我想要一个程序,可以让我向用户拥有的进程发送 SIGHUP或者允许上帝用户发送 SIGHUP 到init
.
该程序在文件上设置了 CAP_KILL 功能。
伪代码可能类似于:
drop_effective CAP_KILL
repeat forever:
get_process_id_from user
if process_id==1 and user_is_God:
set_effective CAP_KILL
kill(-1,1)
drop_effective CAP_KILL
else:
kill(-1,process_id)
这里明显的错误是,我没有首先检查是否允许用户发送信号。因为我已经删除了有效的 CAP_KILL 权限,所以我不会允许用户终止除他们自己的进程之外的进程。
非常做作,当然!但其想法是尽可能以“最小权限”运行,并且仅在必要时启用权限。
现在,这不一定能防止缓冲区溢出攻击,因为注入的代码可以启用允许的权限,因此功能感知代码也应该在不再需要时删除允许的权限;例如,网络服务器在绑定到端口 80 后可能会删除 CAP_NET_BIND_SERVICE。您无法启用不在允许范围内的内容!
答案2
快速假设它可能有用:您希望用户能够复制(读取)系统上的任何文件,但不能更改(写入)它们。您可以有一个程序CAP_DAC_OVERRIDE
(忽略权限检查),其工作方式类似于cp
.但为了确保不允许备份用户覆盖任意文件,它可以CAP_DAC_OVERRIDE
在打开每个输出文件之前从有效集中删除。
至于你的额外问题:如果可以运行任意代码,没有什么可以阻止它们恢复有效。但它在发生其他妥协的情况下可能很有用(例如,您说服程序尝试通过符号链接攻击覆盖任意文件)。