无法使用python切换回root用户

Raj*_*mar 8 python

我以root用户身份登录终端.

然后在Python中:

os.setuid(471)能够切换到子根,但当我尝试切换回root用户时,os.setuid(0)我收到以下错误:Operation not permitted

请让我知道如何从子根切换回root用户.

use*_*342 10

调用os.fork()并切换到子进程中的非root用户."退回"只需退出孩子并等待孩子退出父母.例如:

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)
Run Code Online (Sandbox Code Playgroud)


Cor*_*bin 8

这不是setuid的工作方式.当root降级时,设计根本无法重新获得.一旦你放弃root(在这种情况下),它就消失了.

如果您以root用户身份使用setuid,则无法返回.

我假设os.setuid是一个瘦代理到C级调用.从手册页:

如果用户是root用户或程序是set-user-ID-root,则必须特别小心.setuid()函数检查调用者的有效用户ID,如果是超级用户,则所有与进程相关的用户ID都设置为uid.发生这种情况后,程序无法重新获得root权限.


至于为什么 root不能重新获得,考虑一个典型的用途.想象一下,Apache服务器可以下载到www(或某种非特权用户)以处理实际请求.如果你可以重新获得root,那么Python脚本(或PHP/Perl/CGI /等)可能会重新获得根,并造成绝对的破坏.


至于解决方案,你可以使用seteuid(os.seteuid - 再次,一个简单的代理到C级seteuid).关于setuid和seteuid的python文档看起来很糟糕,但是有大量关于系统调用的文档.

至于暂时掉根和恢复的安全性......你需要非常小心.如果恶意代码有机会获得root权限,那你就搞砸了.出于这个原因,分叉到子进程是一个好主意(如建议用户4815162342).子进程将无法重新root.有关这些问题的更多信息,请点击此处.更多关于setuid的一般奇怪之处在这里.

我们的想法是使用seteuid设置有效的用户ID并生成一个新进程.由于exec的工作方式,有效的用户ID将被复制到新进程的已保存的uid中.由于保存的uid不再是root,因此无法将root更改回.然而,这里可以找到更有趣的文档.

最相关的部分:

如果在filename指向的程序文件上设置了set-user-ID位,并且未挂载基础文件系统nosuid(mount(2)的MS_NOSUID标志),并且调用进程未被ptraced,那么调用进程的有效用户ID更改为程序文件所有者的有效用户ID.类似地,当设置程序文件的set-group-ID位时,将调用进程的有效组ID设置为程序文件的组.

进程的有效用户ID将复制到已保存的set-user-ID; 类似地,有效组ID被复制到保存的集合组ID.此复制发生在由于set-user-ID和set-group-ID权限位而发生的任何有效ID更改之后.


hoj*_*oju 5

使用 seteuid() 来设置有效 ID 但保持权限:

import os
os.seteuid(471)
...
os.seteuid(os.getuid())
Run Code Online (Sandbox Code Playgroud)