Cannot return to root user using python

I entered the terminal as root user.

Then in Python:

os.setuid(471) may switch to sub-root, but when I try to switch to root using os.setuid(0) , I get the following error: Operation not permitted

Please let me know how to switch back to the root user from undermining.

+7
source share
3 answers

Call os.fork() and switch to a non-root user in the child process. Go back by simply exiting the child and waiting for the child to exit the parent. For example:

 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) 
+9
source

This is not how setuid works. When a root depersonalizes itself, by design it cannot be restored to root. As soon as you give up root (in this context), it disappears.

If you use setuid as root, you cannot return.

I assume os.setuid is a thin proxy before level C is called. On the man page:

If the root user or program is installed, then the user ID root must be especially respected. The setuid () function checks the effective user ID of the caller, and if he is the superuser, all user IDs associated with the process are set to uid. After that, the program will not be able to restore root privileges.


As to why root cannot be obtained, consider typical use. Imagine an Apache server that goes down to www (or some non-privileged user) to handle actual requests. If you can restore root, a Python script (or PHP / Perl / CGI / etc) can restore root and cause complete chaos.


As for the solution, you can use seteuid instead (os.seteuid - once again, a simple proxy to level C seteuid ). The python documentation on setuid and seteuid looks pretty bad, but there is a ton of documentation on system calls.

As for the security of temporary root abandonment and restoration ... you need to be very careful. If the malicious code has the ability to get root, you will be screwed. For this reason, it would be nice to branch out the child process (as suggested by user 4815162342). The child process will not be able to restore the root directory. More about the problems can be found here . Read more about the common oddities of setuid here .

The idea is to set an effective user id using seteuid and create a new process. Due to how exec works, the effective user ID will be copied to the saved uid of the new process. Since the stored uid is no longer the root, root cannot be changed back. More interesting documentation can be found here .

The most important parts:

If the installation identifier bit is set in the program file pointed to by the file name, and the base file system is not set to nosuid (MS_NOSUID flag for mount (2)), and the calling process is not processed, the effective user identifier of the calling process is changed to the name of the owner program file. Similarly, when the set-group-ID bit of a program file is set, the effective group identifier of the calling process is set to the program file group.

The effective process user ID is copied to the stored set-user-ID; likewise, the effective group identifier is copied to the stored set-group-ID. This copying occurs after any effective identifier changes that occur due to the bits of the user ID set and the group ID set.

+8
source

Use seteuid () instead to set an effective identifier, but keep the privilege:

 import os os.seteuid(471) ... os.seteuid(os.getuid()) 
+3
source

All Articles