Ci sono due casi,
- Vuoi eliminare temporaneamente i privilegi di root durante l'esecuzione del programma setuid
- Vuoi eliminare permanentemente i privilegi di root durante l'esecuzione del programma setuid...
- Puoi farlo temporaneamente impostando l'euid sull'ID utente reale e poi cambiando l'uid in qualsiasi cosa desideri. E più tardi, quando avrai bisogno del privilegio di root, puoi impostare l'id su root e l'ID utente effettivo tornerà a essere root . Questo perché l'ID utente salvato non viene modificato.
- Puoi eliminare i privilegi in modo permanente cambiando immediatamente l'uid in un id utente con privilegi inferiori. Dopo questo non importa cosa non puoi recuperare il privilegio di root.
Caso 1:
Dopo l'avvio dell'esecuzione di un programma setuid
1.seteuid(600);
2.setuid(1000);
3.setuid(0);
In questo caso il privilegio di root può essere riguadagnato.
+----+------+------------+
| uid|euid |saved-uid |
|----|------|------------|
1.|1000| 0 | 0 |
2.|1000| 600 | 0 |
3.|1000| 1000 | 0 |
4.|1000| 0 | 0 |
| | | |
+------------------------+
Caso 2:
Dopo l'avvio dell'esecuzione di un programma setuid ,
1.setuid(1000);
2.setuid(0);
+----+------+------------+
| uid|euid |saved-uid |
|----|------|------------|
1.|1000|0 | 0 |
2.|1000|1000 | 1000 |
| | | |
+------------------------+
In questo caso non puoi recuperare il privilegio di root. Questo può essere verificato con il seguente comando,
cat /proc/PROCID/task/PROCID/status | meno
Uid: 1000 0 0 0
Gid: 1000 0 0 0
Questo comando visualizzerà un Uid e un Gid e avrà 4 campi (i primi tre campi sono quelli di cui ci occupiamo). Qualcosa di simile a quanto sopra
I tre campi rappresentano uid,euid e save-user-id. Puoi introdurre una pausa (un input da parte dell'utente) nel tuo programma setuid e controllare per ogni passo il cat /proc/PROCID/task/PROCID/status | less
comando. Durante ogni passaggio puoi controllare che l'uid salvato venga modificato come indicato.
Se il tuo euid è root e cambi l'uid, i privilegi vengono eliminati in modo permanente. Se l'id utente effettivo non è root, l'id utente salvato non viene mai toccato e puoi riguadagnare il privilegio di root ogni volta che vuoi nel tuo programma.
DESCRIZIONE setuid() imposta l'ID utente effettivo del processo chiamante. Se l'UID effettivo del chiamante èroot, vengono impostati anche l'UID reale e il set-user-ID salvato.
Sotto Linux, setuid() è implementato come la versione POSIX con la funzione _POSIX_SAVED_IDS. Ciò consente a un programma set-user-ID (diverso da root) di eliminare tutti i suoi privilegi utente, eseguire alcune attività senza privilegi e quindi riattivare l'ID utente effettivo originale in modo sicuro.
Se l'utente è root o il programma è set-user-ID-root, è necessario prestare particolare attenzione. La funzione setuid() controlla l'ID utente effettivo del chiamante e se è il superutente, tutti gli ID utente relativi al processo sono impostati su uid. Dopo che ciò si è verificato, è impossibile per il programma recuperare i privilegi di root.
Pertanto, un programma set-user-ID-root che desidera eliminare temporaneamente i privilegi di root, assumere l'identità di un utente non privilegiato e quindi riottenere i privilegi di root in seguito non può utilizzare setuid(). Puoi farlo con seteuid(2).
(dal Linux Programmers' Manual, 21-09-2014, pagina setuid.2
)
Oh! Queste funzioni sono difficili da usare correttamente.
La pagina man afferma che setuid cambierà l'uid reale, salvato ed effettivo. Quindi, dopo la chiamata setuid(1000), tutti e tre cambiano in 1000.
Questo è il caso se e solo se sei euid 0. Nel momento in cui chiami setuid(0)
, tuttavia, sei euid 1000 e salvato uid 0 (controlla getresuid(2)
, Per esempio). Ecco perché puoi riguadagnare i privilegi.