这是(Python)脚本的安全suid /功能包装吗?

时间:2012-02-11 18:46:53

标签: python c sudo suid

(注意:我考虑过Linux,但问题可能适用于其他平台。)

问题: Linux不对#进行suid!脚本也不会激活它们的“Linux功能”。

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

正确的解决方案:让内核允许suid / cap脚本,如果:a)很明显调用者对脚本文件没有权力 - 或者像其他几个操作系统那样做b )将脚本作为/ dev / fd / x传递,参考最初由内核打开的可信文件。

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

我有什么想法?一个二进制包装器,它以安全的方式完成内核所不具备的功能。

我想

  1. 听取已建立的(Python)脚本包装器,这些脚本通过Linux功能并可能从脚本文件中提取到解释器以使它们生效。
  2. 对我在下面提出的包装器发表评论
  3. sudo的问题:sudo不是一个好的包装器,因为它没有帮助内核不会因为刚解释的“脚本被替换”陷阱(“man sudo”下的警告说左右)。


    建议的包装器

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

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

    • 确保没人能操纵脚本(例如世界可写)
    • 要知道suid / capabilities来自包装器,没有关心脚本文件的suid / xattr挂载
    • 解释器(python)是execve()ed,它会从这里得到一个脏环境
    • 它还将获得通过它的其余标准过程环境,这是......(...阅读exec开始的man-pages)
    • 使用#!/ usr / bin / python -E从环境变量中免疫python解释器
    • 自己在脚本中清理环境,或者注意有很多代码是作为副作用运行的,它们会关心其中的一些变量

1 个答案:

答案 0 :(得分:0)

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

它需要做三件事:

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

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

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