3

(注意:我想到的是 Linux,但这个问题可能适用于其他平台。)

问题: Linux 不执行 suid #! 脚本也不会在它们上激活“Linux 功能”。

为什么我们会遇到这个问题?因为在内核解释器设置运行脚本期间,攻击者可能已经替换了该文件。如何?以前受信任的 suid/capability-enabled 脚本文件可能位于他可以控制的目录中(例如,可以删除不属于他的受信任文件,或者该文件实际上是他拥有的符号链接)。

正确的解决方案:在以下情况下使内核允许 suid/cap 脚本:a) 很明显调用者对脚本文件没有权力 - 或者 - 像其他几个操作系统一样 b) 将脚本作为 /dev/fd/ 传递x,指的是最初内核打开的可信文件。

我正在寻找的答案:对于无法做到这一点的内核(所​​有 Linux),我需要一个安全的“现在”解决方案。

我有什么想法?一个二进制包装器,它以安全的方式执行内核不执行的操作。

我想

  1. 听取已建立的(Python)脚本包装器的消息,这些包装器将 Linux 功能和可能的 suid 从脚本文件传递到解释器以使其有效。
  2. 获得对我在下面提出的包装器的评论

sudo 的问题:sudo 不是一个好的包装器,因为它无助于内核不陷入刚刚解释的“脚本被替换”陷阱(警告下的“man sudo”是这样说的)。


建议的包装器

  • 实际上,我想要一个生成包装器的小程序
    • 命令行,例如:sudo suid_capability_wrapper ./script.py
    • script.py 已经设置了 suid 位和功能(没有功能,只是信息)
  • 生成器 suid_capability_wrapper 确实
    • 生成 C(?) 源代码并编译
    • 将输出编译为: default: basename script.py .py,或参数 -o
    • 像 script.py 一样设置包装器所有者、组、suid
    • 设置允许的功能,如 script.py,忽略可继承和有效的上限
    • 如果解释器(例如 /usr/bin/python)在其可继承集中没有相应的大写字母,则发出警告(这是系统限制:没有 suid-root 否则无法传递能力)
  • 生成的代码会:
    • 检查文件描述符 0、1 和 2 是否打开,否则中止(可能为过于疯狂的环境条件添加更多检查)
    • 如果编译的目标脚本是用相对路径编译的,则通过 /proc/self/exe 确定 self 的位置
    • 将自己的路径与脚本的相对路径结合起来找到它
    • 检查目标脚本所有者、组、权限、大写、suid 是否仍然像原来的(编译的)[这是我想要包括的唯一非必要的安全检查:否则我信任该脚本]
    • 将继承的能力集设置为允许的能力集
    • execve() 解释器类似于内核所做的,但使用我们知道的脚本路径和我们得到的环境(脚本应该照顾环境)

suid_capability_wrapper 可能会打印一堆注释和警告,以教育用户:

  • 确保没有人可以操纵脚本(例如世界可写)
  • 请注意 suid/capabilities 来自包装器,没有人关心脚本文件的 suid/xattr 挂载
  • 解释器(python)是 execve()ed,它会从这里得到一个肮脏的环境
  • 它还将通过它传递标准流程环境的其余部分,即…………(阅读 exec 手册页开始)
  • 使用 #!/usr/bin/python -E 使 python 解释器免受环境变量的影响
  • 在脚本中自己清理环境,或者注意有很多代码作为副作用运行,它们确实关心其中一些变量
4

1 回答 1

0

您根本不想在任何文件上使用 shebang - 您想使用调用 Python 解释器的二进制文件,然后告诉它启动您要求的脚本文件。

它需要做三件事:

  • 启动 Python 解释器(从受信任的路径,打破 chroot 监狱等)。我建议静态链接 libpython 并为此使用 CPython API,但这取决于您。
  • 打开脚本文件 FD 并自动检查它是否为 suid 并由 root 拥有。不允许在检查和执行之间更改文件 - 小心。
  • 告诉 CPython 从您之前打开的 FD 执行脚本。

这将为您提供一个二进制文件,它将仅在 Python 下执行所有由 root 和 suid 拥有的脚本。您只需要一个这样的程序,而不是每个脚本一个。这是你的“suidpythonrunner”。

正如您所猜测的,您必须在运行 Python 之前清除环境。LD_LIBRARY_PATH由内核处理,但PYTHONPATH可能是致命的。

于 2012-02-11T19:02:43.553 回答