![防止 POSIX 功能扩散](https://linux22.com/image/211727/%E9%98%B2%E6%AD%A2%20POSIX%20%E5%8A%9F%E8%83%BD%E6%89%A9%E6%95%A3.png)
一般来说,unix(或者特别是Linux)程序不能执行类似使用ICMP_ECHO(“ping”)来检查路由器的可访问性的操作,除非任何一个由超级用户运行或者setuid 根或者拥有适当的 POSIX 功能。显然,在任何正常运行的系统上,将 setuid 或 POSIX 功能应用于二进制文件都需要超级用户干预。
如果开发环境拥有 CAP_SETFCAP 功能,那么它应该能够在其构建的程序上设置适当的 POSIX 功能,至少就本地操作而言。
向肯·汤普森致敬关于信任信任的思考论文并假设所有库的静态链接,原则上应该可以在每个程序源模块中构建指纹,将其传播到对象和二进制文件,从而提供审计跟踪,证明特定的二进制文件已被由特定的资源集合构建而成。因此,要求祝福新建的 IDE 副本的管理员应该能够满足自己的要求,即 IDE 只能在它自己生成的程序中设置功能,并且不会被恶意用户修改,以便他可以通过例如未记录的启动选项将其用作 setcap 的个人副本。
这里的问题是大多数成熟的开发环境(例如拉撒路集成开发环境)可以自行构建,因此,如果本地管理员使用 CAP_SETFCAP 祝福可证明干净的副本,则恶意用户可以重建它以包含恶意代码并自行对其应用 CAP_SETFCAP,从而破坏本地系统安全。
是否可以将 POSIX CAP_SETFCAP 功能应用于二进制文件,使其无法传播到新建程序的是另一个 CAP_SETFCAP 或其超集功能之一?
答案1
如果您想将使用权保留setcap
给刚刚sudo
启用的用户,则无需为其添加任何功能。就这么做吧。
如果您对可信用户有一定的概念,那么您有两种使用功能的选项。如果您只想表现得好像您有能力,也许还包括包文件等,我还提供了第三个选项。
- 制作 的本地副本
setcap
,将其使用限制为公共组(建设者)的用户并赋予其允许的能力。这信任该组的用户成员表现良好:
$ cp $(which setcap) ./builder-setcap
$ sudo chgrp builders ./builder-setcap
$ chmod 0750 ./builder-setcap
$ sudo ./builder-setcap cap_setfcap=p ./builder-setcap
- 使用可继承文件功能来限制谁可以导致
builder-setcap
以特权运行。这将需要另一个步骤来在运行时实际获取该权限(运行用户预先获取进程的某种方式)可继承能力,例如capsh
或pam_cap.so
)。该机制可能是构建系统的包装器。它capsh
是这样的:
$ cp $(which setcap) ./builder-setcap
$ sudo chgrp builders ./builder-setcap
$ chmod 0750 ./builder-setcap
$ sudo ./builder-setcap cap_setfcap=i ./builder-setcap
$ sudo capsh --user=$(whoami) --inh=cap_setfcap --
... $ # in this shell cap_setfcap is available to ./builder-setcap
- 第三种机制是使用用户命名空间容器。在这样的容器里,有一个虚假的特权概念和一个虚假的概念。根用户。在该环境中,非特权用户被转变为根对于这个容器,并且可以简单地调用
setcap
来授予它假功能:
$ unshare -Ur
... $ id
uid=0(root) gid=0(root) groups=0(root),65534(nobody)
... $ cp $(which setcap) builder-setcap
... $ ./builder-setcap cap_setfcap=p ./builder-setcap
在最后一种情况下,在容器内部时,该文件功能可以工作,但是一旦退出它。启用功能的文件实际上并不具有功能:
... $ exit
$ getcap -n ./builder-setcap
./builder-setcap cap_setfcap=p [rootid=1000]
这里的参数-n
揭示了用户名称空间根身份。您可以看到,在命名空间之外,该文件实际上并不具有文件功能,如下所示:
$ ./builder-setcap -r builder-setcap
unable to set CAP_SETFCAP effective capability: Operation not permitted
我认为对于您想要做的事情来说,最可行的方法是自己编写一个构建调用包装器,其功能相当于方法 2,并按照方法 2sudo capsh --user=$(whoami) --inh=cap_setfcap -- -c 'exec builder'
准备二进制文件。builder-setcap
当然,builder-setcap
如果您想授予某些功能但不授予其他功能,您也可以编写自己的版本来过滤您愿意授予的文件功能。总的代码复杂度setcap
为相当小。
答案2
几年前我也遇到过类似的问题。
一名员工接到任务,负责生成有关本地网络协议使用情况的统计数据。他会使用 python 使用 PACKET_RAW 读取数据包。
但使用 PACKET 需要 CAP_NET_RAW。
将 CAP_NET_RAW 赋予 Python 是一个禁忌,因为其他人会从该特权中受益。给员工 sudo 也是禁忌,因为他是初级员工。
我的解决方案是专门为此编写一个启动器。启动器具有 CAP_NET_RAW 权限,并在 Ambient 集中使用 CAP_NET_RAW 启动 python。启动器所有者是 root,只能由特定用户执行,其他任何人都无法读取。
启动器工作正常,但我们从未审核过该设计的安全性。