即使在seteuid之后也不能在python中删除Root priv。虫子?

2024-09-29 21:31:34 发布

您现在位置:Python中文网/ 问答频道 /正文

即使在seteuid之后也不能在python中删除Root priv。虫子?在

编辑摘要:我忘了删除gid。不过,接受的答案可能会对你有所帮助。在

嗨。我不能放弃linux上python3.2中的root权限。实际上,即使在seteuid(1000)之后,它也可以读取根用户拥有的400模式文件。euid肯定设置为1000!在

我发现之后就空了os.fork操作系统()调用,特权访问被正确拒绝。(但只在父母身上。孩子仍然可以非法阅读。)这是python中的一个bug,还是linux中的bug?在

请尝试下面的代码。注释掉底部三行中的一行,并以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()

Tags: thetocloseaccessosdefetcroot
1条回答
网友
1楼 · 发布于 2024-09-29 21:31:34

在Unix系统上操作进程凭据是很棘手的。我强烈建议您彻底了解真实、有效和保存的Set用户id是如何相互关联的。“放弃特权”很容易搞砸。在

关于你的具体观察。。。我想知道是否有一个简单的原因你可能忽略了。{{1>指定文件的{1>和你的cdve}测试不一致。如果/etc/sudoers具有权限mode=440,uid=root,gid=root(这是我系统上的默认权限),并且/etc/group-的mode=400,那么您的行为应该与您描述的完全一致。在

您没有修改进程的GID,所以如果/etc/sudoers是组可读的,这就解释了为什么它总是可读的。fork()不修改进程凭据。但是,在您的示例代码中可能会出现这种情况,因为您检查的是父级和子级中的不同文件。如果/etc/group-没有/etc/sudoers所拥有的组读取权限,这就可以解释明显的问题。在

如果您只想“删除特权”,请使用以下代码:

os.setgid( NEW_GID )
os.setuid( NEW_UID )

一般来说,只有当您的流程需要在流程的整个生命周期内打开或关闭其根权限时,才需要操作有效的用户标识。如果您只需要使用根权限执行一些安装操作,但在这些安装操作完成后将不再需要这些操作,只需使用上面的代码以不可逆转的方式删除它们。在

在Linux上,一个有用的进程凭证操作调试工具是打印/proc/self/status的输出,这个文件的Uid和Gid行显示当前进程持有的真实的、有效的、保存的集和文件id(按顺序)。pythonapi可以用于检索相同的信息,但是可以将此文件的内容视为“真实数据”,避免Python跨平台api的任何潜在复杂性。在

相关问题 更多 >

    热门问题