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

标签 python c sudo suid

(注意:我考虑过Linux,但这个问题可能适用于其他平台。)
问题:Linux不支持suid!脚本也不会激活它们的“Linux功能”。
我们为什么会有这个问题因为在运行脚本的内核解释器安装过程中,攻击者可能已经替换了该文件怎样?以前受信任的suid/capability启用脚本文件可能位于他控制的目录中(例如,可以删除未拥有的受信任文件,或者该文件实际上是他拥有的符号链接)。
正确的解决方案:让内核允许suid/cap脚本,如果:a)很明显调用方对脚本文件没有权限-或者-像其他两个操作系统一样b)将脚本作为/dev/fd/x传递,引用最初内核打开的受信任文件。
我正在寻找的答案是:对于不能做到这一点的内核(所有的Linux),我需要一个安全的“现在”解决方案。
我有什么想法?一个二进制包装器,它以一种安全的方式做内核不做的事情。
我想
听取已建立的(Python)脚本包装器的意见,这些包装器传递Linux功能,并可能将脚本文件suid传递给解释器以使它们有效。
获取对下面建议的包装器的评论
sudo的问题:sudo不是一个好的包装器,因为它不能帮助内核不陷入刚才解释的“script got replaced”陷阱中(“mansudo”在警告中这么说)。
建议的包装器
实际上,我想要一个小程序,它生成包装器
命令行,例如:sudo suid_capability_wrapper./script.py
script.py已经设置了suid位和功能(没有函数,只有信息)
生成器suid_capability_wrapper可以
生成C(?)源代码和编译
将输出编译为:默认值:basename script.py .py,或参数-o
设置wrapper owner,group,suid like script.py
设置允许的功能,如script.py、ignore inheritable和effective caps
如果解释器(例如/usr/bin/python)的可继承集中没有相应的cap,则发出警告(这是一个系统限制:如果没有suid根,则无法传递功能)
生成的代码:
检查文件描述符0、1和2是否打开,否则中止(可能添加更多检查以检查过于疯狂的环境条件)
如果在目标脚本中编译时使用相对路径,请通过/proc/self/exe确定self的位置
将自己的路径与脚本的相对路径合并以找到它
检查目标脚本owner、group、permissions、caps、suid是否仍然与原始脚本(在中编译)相同[这是我要包括的唯一不必要的安全检查:否则我信任该脚本]
将继承的功能集设置为允许的功能集
execve()解释器类似于内核,但是使用我们知道的脚本路径和我们得到的环境(脚本应该处理环境)
suid_capability_wrapper可能会打印一堆注释和警告,以告知用户:
确保没有人可以操作脚本(例如,world writable)
请注意,suid/功能来自包装器,与脚本文件的suid/xattr装载无关
解释器(python)是execve()ed,它将从这里得到一个肮脏的环境
它还将使标准流程环境的其余部分通过它,即。。。... ... (请先阅读exec的手册页)
使用#!/usr/bin/python-E从环境变量免疫python解释器
在脚本中自己清理环境,或者注意有很多代码是作为副作用运行的,它们确实关心这些变量中的一些

最佳答案

你根本不想在任何文件上使用shebang——你想使用一个调用Python解释器的二进制文件,然后告诉它启动你要求的脚本文件。
它需要做三件事:
启动一个Python解释器(从受信任的路径,打破chroot监狱等等)我建议静态链接libpython并为此使用CPython API,但这取决于您。
打开脚本文件FD并原子性地检查它是否同时是suid和root拥有的。不允许在检查和执行之间更改文件-小心。
告诉CPython从前面打开的FD执行脚本。
这将为您提供一个二进制文件,该文件将仅在Python下执行根和suid脚本所有的文件你只需要一个这样的程序,而不是每个脚本一个这是你的“suidpythonrunner”。
正如您所猜测的,在运行Python之前必须清除环境。LD_LIBRARY_PATH由内核处理,但PYTHONPATH可能致命。

关于python - 这是(Python)脚本的安全suid/功能包装器吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9242989/

相关文章:

python - 找不到符号 : _sqlite3_enable_load_extension - sqlite installed via homebrew

c - UDP recvfrom 数据显示不正确

c - 使用管道和永不结束的命令重现 bash 行为

c - 与 printf 一起使用时 C 中 char* 和 int* 之间的区别

python - 使用 NumPy 广播的 View

python - Django:无法从 ForwardManyToOneDescriptor (ForeignKey) 获取模型实例

python - 如何从elasticsearch django返回的查询集中获取数据

Docker:为什么我需要在 Ubuntu 中使用 sudo?

swift - 通过 GUI 获取 sudo 询问密码

r - 如何在 CentOs 中添加新的仓库