大家好 我们正在积极参与这项工作,并在一月份准备了许多强大的发布会。 其中,已经宣布了一套新的Linux管理员课程流,每个人都喜欢。 期待发布,我们传统上会分享有用材料的翻译。
文件权限是SUID可执行文件的一种安全替代方法,但是起初它们似乎有些混乱。
我们都知道
SUID二进制文件是一个
较差的安全解决方案 。 幸运的是,如果您的应用程序需要一些有限的特权,则有一种更有效的方法称为
文件权限 。
如果您想避免详细阅读上面的文章,那么我会节省您的时间:本质上,文件权限允许进程以root身份运行,因此有权执行某些操作,以保存
受此列表限制的某些功能。重置特权并以非特权用户身份运行。 这意味着,如果攻击者设法通过溢出缓冲区或其他漏洞利用来破坏进程,那么他将无法利用进程真正需要的某些最低特权以外的任何东西。
权限对于通常总是以root用户身份运行的服务很有用,但是命令行实用程序呢? 幸运的是,只要您安装了正确的实用程序,它也受支持。 例如,如果使用Ubuntu,则将需要
libcap2-bin
软件包。 您还需要运行一个非古旧的内核(从
2.6.24版本开始)。
这些功能允许您将权限与可执行文件相关联,类似于设置SUID位,但仅适用于一组特定的权限。
setcap
实用程序用于在文件中添加和删除权限。
第一步是选择所需的权限。 对于本文,我假设有一个名为
tracewalk
的网络诊断工具,应该可以使用
原始套接字 。 这通常要求应用程序以root用户身份运行,但是在查看
列表时,事实证明只
CAP_NET_RAW
权限。
假设您位于
tracewalk
二进制文件所在的目录中,则可以按以下方式添加此权限:
sudo setcap cap_net_raw=eip tracewalk
现在,忽略后缀
=eip
以获得许可,我将在几秒钟内讨论这个问题。 请注意,权限名称为小写。 现在,您可以使用以下方法检查是否已正确配置权限:
setcap -v cap_new_raw=eip tracewalk
或者,您可以列出为此可执行文件设置的所有权限:
getcap tracewalk
作为参考,您还可以使用以下命令从可执行文件中删除所有权限:
setcap -r tracewalk
此时,您应该能够以非特权用户身份运行该可执行文件,并且他应该能够使用原始套接字,但不具有root用户拥有的任何其他特权。
那么这个奇怪的后缀
=eip
什么
=eip
? 这将需要对权限的性质有所了解。 每个进程具有三组权限-
有效,可继承和允许(有效,可继承和允许) :
- 有效权限是确定流程实际可以执行的操作的权限。 例如,如果
CAP_NET_RAW
不在有效集中,则它不能处理原始套接字。 - 允许的权限是指通过适当的调用请求进程所允许的权限。 除非专门为请求指定的权限而编写,否则它们不允许进程实际执行任何操作。 这样,您就可以编写过程以仅在真正需要它们时才将关键权限添加到有效集中。
- 可继承权限是可以在子进程的可用集合中继承的权限。 在
fork()
或clone()
操作期间,始终为子进程提供父进程权限的副本,因为此时它仍在执行同一可执行文件。 当调用exec()
(或等效项)将可执行文件替换为另一可执行文件时,将使用继承集。 此时,可用过程集将被继承集掩盖,以获取将用于新过程的可用集。
因此,
setcap
实用程序允许我们为给定的可执行文件独立添加这三个集合的权限。 请注意,对于文件权限,组的含义有所不同:
- 可用文件权限是指可执行文件始终可用的权限,即使调用它的父进程没有权限也是如此。 他们过去被称为“强制”权限。
- 继承的文件权限定义了另一个掩码,该掩码也可以用于从调用过程集中删除权限。 除了调用过程的继承集以外,还使用它们,因此,仅当两个集合中都存在权限时,才继承权限。
- 实际上,有效文件许可权只是一个位,而不是一组,如果已安装,则意味着整个可用集也将被复制到新进程的有效集。 这可以用于向未专门为请求它们而编写的进程添加权限。 由于这是一位,因此如果您为任何权限设置了它,则必须为所有权限设置它。 您可以将其视为传统位,因为它用于允许不支持它们的应用程序使用权限。
通过
setcap
指定权限时
setcap
三个字母
e
,
i
和
p
表示
有效,继承和可访问的集合。 因此,一个较早的规范:
sudo setcap cap_net_raw=eip tracewalk
...表示
CAP_NET_RAW
权限添加到可用和继承的集中,并且还应该设置有效位。 这将替换文件中任何以前设置的权限。 要一次设置多个权限,请使用逗号分隔的列表:
sudo setcap cap_net_admin,cap_net_raw=eip tracewalk
权限指南将更详细地讨论所有这些内容,但希望本文能使事件更加神秘。 剩下的只是一些警告和技巧。
首先,文件功能不适用于符号链接-您必须将它们应用于二进制文件本身(即符号链接的目标)。
其次,它们不适用于解释的脚本。 例如,如果您具有要分配权限的Python脚本,则必须将其分配给Python解释器本身。 显然,这是一个潜在的安全问题,因为使用此解释器执行的所有脚本都将具有指定的权限,尽管这比执行SUID更好。 显然,最常见的解决方法是用C或类似物编写一个单独的可执行文件,该文件可以执行必要的操作并从脚本中调用它。 这类似于Wireshark使用的方法,该方法使用二进制文件
/usr/bin/dumpcap
执行特权操作:
$ getcap /usr/bin/dumpcap /usr/bin/dumpcap = cap_net_admin,cap_net_raw+eip
第三,如果出于明显的安全原因使用
LD_LIBRARY_PATH
环境
LD_LIBRARY_PATH
,则会禁用文件权限
(1) 。 据我所知,这同样适用于
LD_PRELOAD
。
1.由于攻击者显然可以替换其中一个标准库,并使用LD_LIBRARY_PATH
强制优先于系统调用其库,因此攻击者可以以与调用应用程序相同的特权执行自己的任意代码。
仅此而已。 有关该课程计划的详细信息可以在1月24日举行的网络研讨会上找到。