即使在seteuid之后,也无法在python中删除root priv.一个bug?
编辑摘要:我忘了放弃gid.但是,接受的答案可能对你有所帮助.
你好.我不能在我的linux上删除python 3.2中的root权限.实际上,即使在seteuid(1000)之后,它也可以读取root拥有的400模式文件.euid肯定会设置为1000!
我发现在空的os.fork()调用之后,正确拒绝了特权访问.(但它只在父母身上.孩子仍然可以非法阅读.)这是python中的错误,还是linux?
请尝试下面的代码.注释掉底部的三行中的一行,并以root身份运行.
先谢谢.
#!/usr/bin/python3
# Python seteuid pitfall example.
# Run this __as__ the root.
# Here, access to root-owned files /etc/sudoers and /etc/group- are tried.
# Simple access to them *succeeds* even after seteuid(1000) which should fail.
# Three functions, stillRoot(), forkCase() and workAround() are defined.
# The first two seem wrong. In the last one, access fails, as desired.
# ***Comment out*** one of three lines at the bottom before execution.
# If your python is < 3.2, comment out the entire def of forkCase()
import os
def stillRoot():
"""Open succeeds, but it should fail."""
os.seteuid(1000)
open('/etc/sudoers').close()
def forkCase():
"""Child can still open it. Wow."""
# setresuid needs python 3.2
os.setresuid(1000, 1000, 0)
pid = os.fork()
if pid == 0:
# They're surely 1000, not 0!
print('uid: ', os.getuid(), 'euid: ', os.geteuid())
open('/etc/sudoers').close()
print('open succeeded in child.')
exit()
else:
print('child pid: ', pid)
open('/etc/group-').close()
print('parent succeeded to open.')
def workAround():
"""So, a dummy fork after seteuid is necessary?"""
os.seteuid(1000)
pid = os.fork()
if pid == 0:
exit(0)
else:
os.wait()
open('/etc/group-').close()
## Run one of them.
# stillRoot()
# forkCase()
# workAround()
Run Code Online (Sandbox Code Playgroud)
在Unix系统上操作进程凭据非常棘手.我强烈建议您彻底了解Real,Effective和Saved-Set用户ID是如何相互关联的.搞砸"删除权限"非常容易.
至于你的具体观察......我想知道是否有一个你可能忽略的简单原因.您的代码正在执行不一致的测试,并且您忽略了在您/etc/sudoers和/etc/group-文件上指定确切的文件权限.如果/etc/sudoers权限模式= 440,uid = root,gid = root(这是我系统的默认权限)以及/etc/group-模式= 400 ,那么您的预期行为将完全如您所描述的那样.
你没有修改进程的GID,所以如果/etc/sudoers是组可读的,那就可以解释为什么它总是可读的.fork()不会修改进程凭据.但是,您可能会在示例代码中执行此操作,因为您正在检查父级和子级中的不同文件.如果/etc/group-没有组读取权限/etc/sudoers,那将解释明显的问题.
如果你要做的只是"删除权限",请使用以下代码:
os.setgid( NEW_GID )
os.setuid( NEW_UID )
Run Code Online (Sandbox Code Playgroud)
一般来说,如果您的流程需要在流程的整个生命周期内打开和关闭其root权限,那么您只需要操纵有效的用户ID.如果您只需要使用root权限进行一些设置操作,但在完成这些设置操作后将不再需要它们,只需使用上面的代码就可以不可撤销地删除它们.
哦,Linux上进程凭证操作的一个有用的调试实用程序是打印输出/proc/self/status,该文件的Uid和Gid行显示当前进程持有的真实,有效,保存集和文件ID(按此顺序) ).Python API可用于检索相同的信息,但您可以将此文件的内容视为"真实数据",并避免Python跨平台API的任何潜在复杂情况.
| 归档时间: |
|
| 查看次数: |
2102 次 |
| 最近记录: |