防止 POSIX 功能扩散

防止 POSIX 功能扩散

一般来说,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启用的用户,则无需为其添加任何功能。就这么做吧。

如果您对可信用户有一定的概念,那么您有两种使用功能的选项。如果您只想表现得好像您有能力,也许还包括包文件等,我还提供了第三个选项。

  1. 制作 的本地副本setcap,将其使用限制为公共组(建设者)的用户并赋予其允许的能力。这信任该组的用户成员表现良好:
$ cp $(which setcap) ./builder-setcap
$ sudo chgrp builders ./builder-setcap
$ chmod 0750 ./builder-setcap
$ sudo ./builder-setcap cap_setfcap=p ./builder-setcap
  1. 使用可继承文件功能来限制谁可以导致builder-setcap以特权运行。这将需要另一个步骤来在运行时实际获取该权限(运行用户预先获取进程的某种方式)可继承能力,例如capshpam_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
  1. 第三种机制是使用用户命名空间容器。在这样的容器里,有一个虚假的特权概念和一个虚假的概念。用户。在该环境中,非特权用户被转变为对于这个容器,并且可以简单地调用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,只能由特定用户执行,其他任何人都无法读取。
启动器工作正常,但我们从未审核过该设计的安全性。

相关内容