Aperçu
L'appel système setuid modifie l'ID utilisateur d'un processus, permettant à ce processus de s'exécuter avec les privilèges d'un utilisateur spécifique. Cela réduit les vulnérabilités de sécurité et est essentiel pour les programmes conçus pour utiliser des privilèges élevés uniquement lorsque nécessaire. Il est généralement utilisé par les programmes SUID exécutés avec les privilèges root pour revenir aux privilèges d'un utilisateur normal après avoir effectué certaines tâches.
Fonctionnalités principales
- Gestion des autorisations: Contrôle les autorisations en modifiant les ID utilisateur réels, effectifs et sauvegardés d'un processus.
- Renforcement de la sécurité: Réduit les risques de sécurité potentiels en passant à des privilèges inférieurs pour les tâches qui n'en nécessitent pas.
- Programmes SUID: Utilisé par les programmes avec le bit SUID activé pour augmenter ou diminuer temporairement les privilèges lors de l'exécution avec les droits d'un utilisateur spécifique (par exemple, root).
Exemples d'utilisation
setuid n'est pas une commande exécutée directement dans le shell, mais une fonction système appelée dans un programme C/C++. Voici un exemple conceptuel de l'utilisation de setuid en langage C. Ce code, une fois compilé et avec le bit SUID défini, peut s'exécuter avec les privilèges d'un utilisateur spécifique.
Exécution avec les privilèges root puis passage à un utilisateur normal
#include <unistd.h>\n#include <stdio.h>\n#include <sys/types.h>\n#include <pwd.h>\n\nint main() {\n printf("ID utilisateur effectif actuel : %d\n", geteuid());\n\n // Effectuer des opérations ne pouvant être faites qu'avec les privilèges root (exemple)\n // ...\n\n // Trouver l'UID de l'utilisateur 'nobody' et passer à ces privilèges\n struct passwd *pw = getpwnam("nobody");\n if (pw == NULL) {\n perror("getpwnam");\n return 1;\n }\n\n if (setuid(pw->pw_uid) == -1) {\n perror("setuid");\n return 1;\n }\n\n printf("ID utilisateur effectif après changement : %d\n", geteuid());\n\n // Effectuer maintenant des opérations ne pouvant être faites qu'avec les privilèges de 'nobody'\n // ...\n\n return 0;\n}
Cet exemple montre comment un programme peut démarrer avec les privilèges root, effectuer certaines tâches, puis passer aux privilèges d'un utilisateur normal (ici, 'nobody'). Dans une utilisation réelle, vous devez spécifier l'ID utilisateur approprié.
Compilation et configuration SUID (concept)
gcc -o myprogram myprogram.c\nsudo chown root:root myprogram\nsudo chmod u+s myprogram\n./myprogram
Processus conceptuel pour compiler le code C ci-dessus et définir le bit SUID sur le fichier exécutable avec les privilèges root. **Attention : Les programmes SUID présentent des risques de sécurité importants et doivent être manipulés avec prudence.**
Conseils et précautions
L'appel système setuid est un outil puissant de gestion des autorisations, mais son utilisation incorrecte peut entraîner de graves vulnérabilités de sécurité. Les points suivants doivent impérativement être pris en compte.
Considérations de sécurité
- **Principe du moindre privilège** : Maintenez les privilèges élevés uniquement pendant la durée minimale nécessaire et revenez à des privilèges inférieurs dès que la tâche est terminée.
- **Validation des entrées** : Les programmes SUID doivent toujours effectuer une validation rigoureuse des entrées utilisateur pour prévenir les attaques telles que les dépassements de tampon ou l'injection de commandes.
- **Variables d'environnement** : Les programmes SUID peuvent avoir un comportement inattendu en raison des variables d'environnement (PATH, LD_PRELOAD, etc.). Il est donc conseillé de nettoyer l'environnement au début de l'exécution ou de le réinitialiser à des valeurs sûres.
- **Gestion des erreurs** : Gérez correctement les erreurs en cas d'échec de l'appel setuid et veillez à ce que le programme ne continue pas à s'exécuter avec des privilèges élevés.
- **Éviter setuid(0)** : Passer aux privilèges root avec setuid(0) est très dangereux. Évitez de l'utiliser sauf si absolument nécessaire, et envisagez plutôt d'utiliser `seteuid()` pour modifier uniquement l'ID utilisateur effectif.
Appels système associés
Outre setuid, il existe divers autres appels système pour la gestion des autorisations.
- seteuid(): Modifie uniquement l'ID utilisateur effectif. L'ID utilisateur réel n'est pas modifié, ce qui permet de revenir aux privilèges d'origine si nécessaire.
- setreuid(): Modifie simultanément l'ID utilisateur réel et l'ID utilisateur effectif.
- setresuid(): Fonction flexible permettant de modifier les ID utilisateur réels, effectifs et sauvegardés.
- getuid(), geteuid(): Interroge respectivement l'ID utilisateur réel et l'ID utilisateur effectif du processus courant.