无法使用Python切换回root用户

2024-09-30 04:31:54 发布

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

我以root用户的身份登录到终端。在

然后在Python中:

os.setuid(471)可以切换到subrot,但是当我试图使用os.setuid(0)切换回根用户时,我得到了以下错误:Operation not permitted

请让我知道如何从subrot切换回根用户。在


Tags: 用户终端os错误not身份rootoperation
3条回答

请改用seteuid()来设置有效ID,但要保留特权:

import os
os.seteuid(471)
...
os.seteuid(os.getuid())

setuid不是这样工作的。当根目录降级时,它的设计是不能重新约束根的。一旦你放弃了根(在这种情况下),它就消失了。在

如果使用setuid作为根用户,则无法返回。在

我假设操作系统集UID是一个到C级调用的瘦代理。从man页:

If the user is root or the program is set-user-ID-root, special care must be taken. The setuid() function checks the effective user ID of the caller and if it is the superuser, all process-related user ID's are set to uid. After this has occurred, it is impossible for the program to regain root privileges.


至于为什么根不能被重新训练,考虑一个典型的用法。假设有一个Apache服务器下拉到www(或某种非特权用户)来处理实际的请求。如果您可以重新获得根目录,那么Python脚本(或PHP/Perl/CGI/etc)可能会夺回root并造成绝对的破坏。在


至于解决方案,可以使用seteuid(操作系统集ID再一次,一个简单的代理通过到C级seteuid)。关于setuid和seteuid的python文档看起来很糟糕,但是有大量关于系统调用的文档。在

至于暂时掉根恢复的安全。。。你需要非常小心。如果恶意代码有机会获得根目录,你就完蛋了。出于这个原因,最好是进入一个子进程(如user4815162342所建议的)。子进程将无法重新根。有关关注点的更多信息可以在here找到。关于setuid一般奇怪之处的更多信息是here。在

其思想是用seteuid设置有效的用户id并生成一个新进程。由于exec的工作方式,有效的用户id将被复制到新进程的保存uid中。由于保存的uid不再是root,因此无法将root改回。更多有趣的文档可以找到here。在

最相关的部分:

If the set-user-ID bit is set on the program file pointed to by filename, and the underlying file system is not mounted nosuid (the MS_NOSUID flag for mount(2)), and the calling process is not being ptraced, then the effective user ID of the calling process is changed to that of the owner of the program file. Similarly, when the set-group-ID bit of the program file is set the effective group ID of the calling process is set to the group of the program file.

The effective user ID of the process is copied to the saved set-user-ID; similarly, the effective group ID is copied to the saved set-group-ID. This copying takes place after any effective ID changes that occur because of the set-user-ID and set-group-ID permission bits.

调用os.fork()并切换到子进程中的非根用户。““切换回”只需在子节点中退出,然后等待子节点退出父节点。例如:

pid = os.fork()
if pid == 0:
    # child - do the work and exit
    try:
        os.setuid(471)
        ... do the work here
    finally:
        os._exit(0)

# parent - wait for the child to do its work and keep going as root
os.waitpid(pid, 0)

相关问题 更多 >

    热门问题