suPHP permet d’exécuter des scripts PHP avec les droits de leur propriétaire ! Alors qu’avant si l’on voulais utiliser une commande critique dans un script PHP (avec un bit suid par exemple ou avec sudo) tous les utilisateurs du serveur web pouvait l’exécuter et donc compromettre le serveur, nous pouvons maintenant le faire sans risques !
Voyons ça en détails !
Pour atteindre notre but nous utiliserons tout simplement sudo et la fonction PHP exec () (on peut aussi utiliser system () ou encore passthru) !
Nous allons créer un script PHP qui ajoutera un utilisateur système grâce à la commande useradd. Vous obtiendrez toutes les informations nécessaire à l’utilisation de cette commande en tapant man useradd.
Pour cet exemple, nous considérerons que vous avez un serveur web avec PHP et suPHP d’installer correctement (voir ce How-To). L’utilisateur que nous utiliserons pour nos tests s’appellera très originalement Kévin, nous supposerons que ce compte existe et qu’il est fonctionnel. Le script que nous créerons ce nommera useradd.php et se trouvera dans le répertoire /var/www/Kévin/. Nous utiliserons un formulaire pour indiquer le nom d’utilisateur a ajouter ainsi que son mot de passe, ce formulaire sera dans la page useradd.html du le même répertoire.
Notez que pour une sécurité maximum il est judicieux de créer un utilisateur sans shell (indiquez /bin/false ou /sbin/nologin comme shell) pour exécuter nos scripts PHP critiques. De plus il faudra veiller à ce que votre script soit exempt de failles de sécurités, celle-ci pouvant compromettre gravement votre système ! Enfin veillez bien entendu à ce que les scripts ne soient pas ouvert en écriture (pas de chmod 777 !!!) !
Les règles sudo
Définissons tout d’abord les règles sudo nécessaire pour lancer la commande useradd
depuis notre script. Lancez la commande visudo
en tant que root et ajoutez cette règle: Kévin ALL= NOPASSWD: /usr/sbin/useradd *
Nous indiquons que l’utilisateur Kévin peut exécuter le programme /usr/sbin/useradd
sans avoir à indiquer de mot de passe.
Vous obtiendrez plus d’information sur la configuration de sudo en tapant $ man sudoers
ou en consultant ce document sur Lea-linux.
Maintenant que sudo est configuré, codons !
Le formulaire
Ce formulaire n’est qu’une simple page web: /var/www/Kévin/useradd.html. Cette page se contente de transmettre le login et le mot de passe du compte a ajouter à useradd.php via la méthode POST.
<?xml version="1.0" encoding="ISO-8859-15"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//En" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> <head> <title>Ajouter un utilisateur</title> </head> <body> <h1>Ajouter un utilisateur système</h1> <form action="useradd.php" method="post"> <p> <label for="login">Nom d'utilisateur</label>: <input type="text" name="login" id="login" /><br /> <label for="pass">Mot de passe</label>: <input type="password" name="pass" id="pass" /><br /> <input type="submit" /> </p> </form> </body> </html>
Le script PHP
Maintenant examinons le code de useradd.php (licence GPL):
<?php exec ('/usr/bin/sudo /usr/sbin/useradd -m -p ' . escapeshellarg (crypt ($_POST['pass'])) . ' ' . escapeshellarg ($_POST['login']), $sortie, $retour); if ($retour == 0) echo 'L\'utilisateur <strong>' . $_POST['login'] . '</strong> a bien été créé.'; else echo 'Erreur ! Impossible de créer l\'utilisateur <strong>' . $_POST['login'] . '</strong>.'; ?>
Ce script est en réalité très simple:
Nous commençons par lancer la commande sudo
(configurée plus haut) qui nous permet d’exécuter useradd
. Commencez par consulter la documentation des fonctions PHP permettant l’exécution de programmes externes et la page man de useradd.
Remarquez que l’on utilise les chemins complets des exécutables sudo
et useradd
. C’est dans le but d’éviter des bugs et/ou problèmes de sécurité liés à la mauvaise configuration, ou à l’absence de la variable d’environnement PATH.
Chaque paramètre est vérifié à l’aide de la fonction escapeshellarg (). Cette fonction permet d’éviter que le système soit compromis suite au passage d’arguments volontairement erronés. Il est impératif de l’utiliser pour chaque argument fourni par l’utilisateur.
De même chaque commande provenant de l’extérieur (variable $_POST, $_GET, base de donnée, …) doit être vérifiée avec escapeshellcmd () !
Nous ajoutons un utilisateur grâce à la commande useradd
. -m spécifie que le répertoire personnel (home) doit-être créé, -p permet de définir un mot de passe (indiquer sous forme cryptée avec crypt ()). Les deux dernières lignes effectuent une petite gestion des erreurs. Si le code de statut de réponse UNIX est égal à 0 alors tout c’est bien passé sans quoi une erreur c’est produite.
Le principal est dit ! Grâce à cet exemple vous pouvez entrevoir les possibilités que vous offre suPHP, à vous de les exploiter !