【问题标题】:How to execve a process, retaining capabilities in spite of missing filesystem-based capabilities?尽管缺少基于文件系统的功能,如何执行进程并保留功能?
【发布时间】:2013-01-31 22:31:29
【问题描述】:

我想让系统在没有setuid、文件“+p”功能的情况下也可以使用,并且通常没有在我设置PR_SET_NO_NEW_PRIVS时被禁用的东西。

使用这种方法(init 设置 PR_SET_NO_NEW_PRIVS 和基于文件系统的能力提升不再可能)你不能“重新填充”你的能力,只需要小心不要“飞溅”它们。

如何execve 其他进程而不“破坏”任何授予的功能(例如,如果新程序的文件是setcap =ei)?只是“我相信这个新过程,就像我相信自己一样”。例如,给用户一个能力(并且用户想在他启动的任何程序中使用它)......

我可以永久创建整个文件系统=ei吗?我想保持文件系统不干扰方案,不能授予或撤销功能;通过父->子控制一切。

【问题讨论】:

  • 您能否澄清一点,在您的标题中您写道“尽管缺少文件功能”,在您的问题中您说您想使用此功能并将整个文件的功能位设置为 ei。您的系统中是否存在该功能?
  • 表示文件系统功能不允许 +i 用于例如用户刚刚编译的文件,但我们仍然希望该用户能够使用此功能。使用 +i 获取功能只能作为进程(用户)的 +i 和文件系统的 +i 之间的交集。如果没有文件系统的竞争(没有 +p 和没有 +i),我就无法运行其他可执行文件来保留我已经拥有的有效能力。这造成了差异(即可以加载将使用我的功能的动态库,但该库无法在不丢失上限的情况下生成进程)。
  • 所以它工作正常,但不像你预期的那样。

标签: linux execve linux-capabilities


【解决方案1】:

我并不是说我为你正在做的事情推荐这个,但它就是这样。

摘自手册,有一些改动。据它说:fork 不会改变功能。而且现在在 Linux 内核 4.3 中添加了一个环境设置,这似乎是你想要做的。

   Ambient (since Linux 4.3):
          This is a set of capabilities that are preserved across an execve(2) of a program that is not privileged.  The ambient capability set obeys the invariant that no capability can ever
          be ambient if it is not both permitted and inheritable.

          The ambient capability set can be directly modified using
          prctl(2).  Ambient capabilities are automatically lowered if
          either of the corresponding permitted or inheritable
          capabilities is lowered.

          Executing a program that changes UID or GID due to the set-
          user-ID or set-group-ID bits or executing a program that has
          any file capabilities set will clear the ambient set.  Ambient
          capabilities are added to the permitted set and assigned to
          the effective set when execve(2) is called.

   A child created via fork(2) inherits copies of its parent's
   capability sets.  See below for a discussion of the treatment of
   capabilities during execve(2).

Transformation of capabilities during execve()
   During an execve(2), the kernel calculates the new capabilities of
   the process using the following algorithm:

       P'(ambient) = (file is privileged) ? 0 : P(ambient)

       P'(permitted) = (P(inheritable) & F(inheritable)) |
                       (F(permitted) & cap_bset) | P'(ambient)

       P'(effective) = F(effective) ? P'(permitted) : P'(ambient)

       P'(inheritable) = P(inheritable)    [i.e., unchanged]

   where:

       P         denotes the value of a thread capability set before the
                 execve(2)

       P'        denotes the value of a thread capability set after the
                 execve(2)

       F         denotes a file capability set

       cap_bset  is the value of the capability bounding set (described
                 below).

   A privileged file is one that has capabilities or has the set-user-ID
   or set-group-ID bit set.

【讨论】:

  • 在我的工具dived中实现设置环境功能。
  • @vi 你能用一个完整的句子再说一遍吗?
  • 我到处寻找一个允许试验环境能力的工具,但没有找到(尤其是在 Debian Stable 上)。所以我在我自己的工具“潜水”中添加了另一个选项。为了帮助其他想要在不等待适当的工具和库赶上的情况下使用环境功能的用户,我决定在相关的地方发布一个链接。这个让我了解该功能的答案似乎是这个相关的地方。
【解决方案2】:

如果您参考功能手册页,目前没有简单的方法可以做到这一点:

During an execve(2), the kernel calculates the new capabilities of the process
using the following algorithm:

P'(permitted) = (P(inheritable) & F(inheritable)) | (F(permitted) & cap_bset)

P'(effective) = F(effective) ? P'(permitted) : 0 

P'(inheritable) = P(inheritable)    [i.e., unchanged]

where:

P        denotes the value of a thread capability set before the execve(2)
P'       denotes the value of a capability set after the execve(2)
F        denotes a file capability set
cap_bset is the value of the capability bounding set 

如果您要执行的文件未设置其 fP 位,或者未设置其 fI 位,则您的进程将没有被允许的权限,因此没有有效的功能。

设置整个文件系统允许和继承位在技术上是可行的,但这没有多大意义,因为它会大大降低系统的安全性,(编辑:正如你提到的,这不适用于新的可执行文件) .

您确实可以使用 pam_cap 为用户提供一些功能,但是您不能让他们执行他们刚刚使用它编译的任何文件。功能是为程序而不是用户而设计的,您可以阅读Hallyn's paper

一个关键的见解是观察到程序而不是人在锻炼 特权。也就是说,在计算机中完成的所有事情都是通过 代理——程序——并且只有在这些程序知道如何处理的情况下 是否可以信任他们使用它的特权。

另见POSIX draft 1003.1e,它定义了 POSIX 功能,第 310 页:

也不宜为流程链(a 单个进程内的程序序列)一组能力 在该链的整个生命周期中保持固定和活跃。 [...] 这是最小特权原则的应用,它 同样适用于用户和进程。

最近(2012 年 12 月)有人要求在this Linux 内核邮件列表中介绍您想要作为一个功能做什么,并且给出了一些非常有趣的答案。有些人认为,在exec 的继承规则中删除文件功能会引入一些安全问题,并且功能不是为此类功能设计的,即使没有解释它会引入哪个安全问题:/

目前唯一的方法是修改在 Linux 内核中继承功能的方式(要修改 2 个文件,我在 3.7 内核上成功测试过),但不清楚这是否安全,如前所述以上。

在旧内核(2.6.33 之前)上,可以选择在没有文件功能的情况下进行编译 (CONFIG_SECURITY_FILE_CAPABILITIES),但我怀疑使用这样的旧内核是否适合您。

【讨论】:

  • 想象一下我以某种方式运行了一个具有有效权限的程序(shell)。我可以让它动态加载库并执行任何代码。但是也可以方便地加载动态库(只是普通程序)之外的东西。使用 PR_SET_NO_NEW_PRIVS 您无法获得新的权限。但我想要一个工具来防止“丢失”已经存在的权限。
  • Setting the whole file system effective bit -> 或者为 /lib/ld-linux* 设置它。 strongly reduce the security on the system -> 不应该,如果你监督获得 +i 的进程。它将“授予程序权限”转变为“授予用户权限”(即用户可以编译和启动任何行使此权限的程序)。
  • 你不能直接给用户能力,你能更详细地描述你想要实现的目标吗?为什么你不想从你的 shell 设置文件功能,然后只允许你信任的用户运行这个 shell?您是否正在尝试编写程序?破解内核?
  • "从你的 shell 设置文件功能" -> 需要 CAP_SETFCAP。
  • 示例:只允许用户对任何程序(包括他刚刚编译的程序)进行 CAP_NET_BIND_SERVICE。可以使用 PAM 设置此用户的 CAP_NET_BIND_SERVICE+i。 hacky 解决方法包括为 /lib/ld-linux.so.2 设置 +i。
【解决方案3】:

我认为(我的理解),使用功能的最佳方式是:

  • 对于需要功能和受信任的程序,包括受信任的不泄漏功能:例如Wire-shark 的数据包嗅探部分,这是一个需要侦听端口 80 的 Web 服务器。
    • 新程序,功能感知:设置允许。
    • 遗留程序,不知道功能:设置允许和有效
  • 对于会泄漏功能并且具有可以(有时)使用功能的代码的程序:设置继承
    • 例如对于chmod 设置继承CAP_FOWNER,如果用户需要超级权限(通常由root 持有),那么他们需要使用setpriv(或等效,这可以滚动到sudo),否则它在非特权模式下工作。
  • 当一个进程需要分叉和共享某些功能时,只有在那时才使用环境。可能相同的可执行文件;如果它是不同的,那么这个新的将允许或继承文件上的集合。 [编辑:我刚刚意识到,如果您不执行,则不需要环境。如果我想到一个环境的用例,在一个设置良好的系统中,那么我会在这里添加它。 Ambient 可以用作一种过渡机制,当没有在可以使用它的文件上设置继承时。]

环境的使用:

  • 在文件没有正确功能的系统上。 (一种过渡技巧)。
  • 对于 shell 脚本,不能具有功能(因为它们不能具有 setuid),除非系统已修复并允许在脚本上设置 setuid。
  • 在此处添加更多内容。

【讨论】:

  • s/leek/leak/?
  • 可以使用环境功能,例如,仅取消“仅用于 root 的小于 1024 的端口”规则。或者将网络设置代码分解为 shell 脚本,而不在 /bin/sh 上设置任何位。或者当文件系统是哑的并且没有扩展属性时。
  • @Vi 我做了你做的事。顺便说一下s/[?]/g/
  • @Vi 你有一个很好的观点,我没有看到:用于启动 shell 脚本的环境。至于您的第一点,如果您需要侦听端口
猜你喜欢
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-16
  • 2019-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多