2013-01-09 14 views
7

Ho eseguito l'accesso al terminale come utente root.Impossibile tornare all'utente root utilizzando python

Poi in Python:

os.setuid(471) è in grado di passare a subroot ma quando sto cercando di tornare a utente root usando os.setuid(0) Sto ottenendo il seguente errore: Operation not permitted

prega fatemi sapere come ritorna al root utente da subroot.

+0

E cosa vuoi dire sotto subroot? – Denis

risposta

8

Non è così che funziona setuid. Quando root si abbassa, è in base alla progettazione che la radice non può essere reobtain. Una volta che si arrende root (in questo contesto), è sparito.

Se si utilizza setuid come root, non è possibile tornare indietro.

Suppongo che os.setuid sia un proxy sottile fino alla chiamata di livello C. Dalla pagina 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.


Per quanto riguarda il motivo per cui radice non può essere reobtained, considerano un uso tipico. Immagina un server Apache che scende a www (o qualche tipo di utente non privilegiato) per gestire le richieste effettive. Se si potesse riottenere root, uno script Python (o PHP/Perl/CGI/etc), potrebbe riguadagnare root e provocare il caos assoluto.


Per quanto riguarda una soluzione, è possibile utilizzare seteuid invece (os.seteuid - ancora una volta, una semplice delega fino al livello C seteuid). La documentazione Python su setuid e seteuid sembra piuttosto brutta, ma ci sono tonnellate di documentazione sulle chiamate di sistema.

Per quanto riguarda la sicurezza di far cadere temporaneamente la radice e riacquistare ... Dovrai stare molto attento. Se il codice dannoso ha l'opportunità di ottenere la radice, sei fregato. Per questo motivo, è consigliabile inserire un processo figlio (come suggerito dall'utente4815162342). Il processo figlio non sarà in grado di re-root. Maggiori informazioni sulle preoccupazioni possono essere trovate here. Maggiori informazioni sulla stranezza generale di setuid sono here.

L'idea è di impostare l'id utente efficace con seteuid e generare un nuovo processo. A causa del modo in cui funziona exec, l'id utente effettivo verrà copiato nell'uid salvato del nuovo processo. Poiché l'uid salvato non è più root, root non può essere cambiato in. Ancora più divertente documentazione può essere trovata here.

Le parti più rilevanti:

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.

9

chiamata os.fork() e interruttore per l'utente non root nel processo figlio. "Torna indietro" semplicemente uscendo dal bambino e aspettando che il bambino esca dal genitore. Per esempio:

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) 
+0

os.waitpid accetta due argomenti, uno dato – answerSeeker

+0

@answerSeeker Fisso, grazie – user4815162342

3

Usa seteuid() invece per impostare l'ID efficace, ma mantenere il privilegio:

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