RealUID, UID enregistré, UID effectif. Que se passe-t-il?

Ceci est un programme set-root-uid

$ls -l -rwsr-sr-x 1 root root 7406 2011-12-13 22:37 ./x* 

Le code source:

 int main(void) { printf( " UID GID \n" "Real %d Real %d \n" "Effective %d Effective %d \n", getuid (), getgid (), geteuid(), getegid() ); seteuid(600); printf( " UID GID \n" "Real %d Real %d \n" "Effective %d Effective %d \n", getuid (), getgid (), geteuid(), getegid() ); setuid(1000); printf( " UID GID \n" "Real %d Real %d \n" "Effective %d Effective %d \n", getuid (), getgid (), geteuid(), getegid() ); setuid(0); // HOW DOES THIS SUCCEED IN SETTING THE EUID BACK TO 0 printf( " UID GID \n" "Real %d Real %d \n" "Effective %d Effective %d \n", getuid (), getgid (), geteuid(), getegid() ); return 0 ; } 

SORTIE

  UID GID Real 1000 Real 1000 Effective 0 Effective 0 UID GID Real 1000 Real 1000 Effective 600 Effective 0 UID GID Real 1000 Real 1000 Effective 1000 Effective 1000 UID GID Real 1000 Real 1000 Effective 0 Effective 1000 

Ma question

La page de manuel indique que setuid changera l’ID réel, enregistré et effectif. Donc, après le setuid(1000) appel setuid(1000) , tous les trois passent à 1000 . Comment est-ce que setuid(0) me laisse euid à 0 ?

Il y a deux cas,

  1. Vous souhaitez supprimer temporairement les privilèges root lors de l’exécution du programme setuid
  2. Vous voulez supprimer définitivement les privilèges root lors de l’exécution du programme setuid …
  • Vous pouvez le faire temporairement en définissant l’euid sur l’ID utilisateur réel, puis en changeant l’ID utilisateur pour tout ce que vous voulez. En effet, l’ID utilisateur enregistré n’est pas modifié.
  • Vous pouvez supprimer des privilèges de manière permanente en changeant immédiatement l’ID utilisateur en un identifiant d’utilisateur moins privilégié. Après cela, peu importe ce que vous ne pouvez pas récupérer le privilège root.

Cas 1:

Après l’exécution d’un programme setuid

 1.seteuid(600); 2.setuid(1000); 3.setuid(0); 

Dans ce cas, le privilège root peut être rétabli.

  +----+------+------------+ | uid|euid |saved-uid | |----|------|------------| 1.|1000| 0 | 0 | 2.|1000| 600 | 0 | 3.|1000| 1000 | 0 | 4.|1000| 0 | 0 | | | | | +------------------------+ 

Cas 2:

Après l’exécution d’un programme setuid ,

 1.setuid(1000); 2.setuid(0); +----+------+------------+ | uid|euid |saved-uid | |----|------|------------| 1.|1000|0 | 0 | 2.|1000|1000 | 1000 | | | | | +------------------------+ 

Dans ce cas, vous ne pouvez pas récupérer le privilège root. Ceci peut être vérifié par la commande suivante,

cat / proc / PROCID / task / PROCID / status | Moins

 Uid: 1000 0 0 0 Gid: 1000 0 0 0 

Cette commande affichera un Uid et un Gid et aura 4 champs (les trois premiers champs sont ceux qui nous intéressent). Quelque chose comme ci-dessus

Les trois champs représentent uid, euid et saved-user-id. Vous pouvez introduire une pause (une entrée de l’utilisateur) dans votre programme setuid et vérifier pour chaque étape le cat /proc/PROCID/task/PROCID/status | less cat /proc/PROCID/task/PROCID/status | less commande. Au cours de chaque étape, vous pouvez vérifier que l’ID utilisateur enregistré a été modifié comme indiqué.

Si vous êtes root et que vous modifiez l’ID utilisateur, les privilèges sont définitivement supprimés. Si l’ID utilisateur effectif n’est pas root, l’identifiant utilisateur enregistré n’est jamais touché et vous pouvez récupérer les privilèges root à tout moment.

DESCRIPTION setuid () définit l’ID utilisateur effectif du processus appelant. Si l’UID effectif de l’appelant est root, le véritable UID et l’ID utilisateur-set enregistré sont également définis.

Sous Linux, setuid () est implémenté comme la version POSIX avec la fonctionnalité _POSIX_SAVED_IDS. Cela permet à un programme set-user-ID (autre que root) de supprimer tous ses privilèges utilisateur, d’effectuer des tâches non privilégiées, puis de reconnecter l’ID utilisateur effectif d’origine de manière sécurisée.

Si l’utilisateur est root ou si le programme est set-user-ID-root, des précautions particulières doivent être sockets. La fonction setuid () vérifie l’ID utilisateur effectif de l’appelant et, s’il s’agit du superutilisateur, tous les ID utilisateur liés au processus sont définis sur uid. Après cela, il est impossible pour le programme de récupérer les privilèges root.

Ainsi, un programme set-user-ID-root souhaitant supprimer temporairement les privilèges root, assumer l’identité d’un utilisateur non privilégié, puis récupérer les privilèges root par la suite, ne peut pas utiliser setuid (). Vous pouvez accomplir cela avec seteuid (2).

(extrait du Manuel des programmeurs Linux, 2014-09-21, page setuid.2 )

O! Ces fonctions sont difficiles à utiliser correctement.

La page de manuel indique que setuid changera l’ID réel, enregistré et effectif. Donc, après le setuid d’appel (1000), tous les trois passent à 1000.

C’est le cas si et seulement si vous êtes euid 0. Au moment où vous appelez setuid(0) , vous êtes cependant euid 1000 et enregistré uid 0 (vérifiez getresuid(2) , par exemple). C’est pourquoi vous êtes en mesure de retrouver des privilèges.