Code Tips and Snippets


Pas encore membre ?
Cliquez ici pour vous inscrire.
Vous pourrez poster des commentaires.
Exécuter des scripts php (ou autres) en suid root
Posté par pk le Dimanche 07 Septembre 2014 à 12:45:15
Niveau 5 étoilesLangage CLangage phpSystème d'exploitation Linux

Qui n’à jamais eu le besoin d’exécuter certains scripts php (ou autres), qui nécessitent d’accéder à des données en root, par des utilisateurs non privilégiés (voir par apache par exemple).

En fait, cela se fait très facilement pour un programme C.

Mais pour un script (autre que sh ou bash ...), dans les distributions récentes, c’est interdit pour des soi-disant considérations de sécurité.
Peut-être que cela serait justifié sur un serveur où une multitude d’utilisateurs ont accès en local avec des permissions non maîtrisées par l’administrateur...
Sur un serveur personnel, où seuls des services (web,mél, etc.) sont proposés au public, je trouve cela complètement infondé !

Voyons comment contourner les restrictions totalitaires des distributions actuelles.

La clé réside dans le fait que cela est très facile à faire en C !
il suffit donc d’écrire un minuscule programme C qui lui lancera notre script en root !

Commençons par voir comment cela se passe pour un programme C :
Il faut qu’il ait dans son code les 2 lignes suivantes :

 
    setuid(0);    // set effective user  id 0 (root uid)
    setgid(0);    // set effective group id 0 (root gid)

Veuillez vous référer aux man setuid  et man setgid pour le manuel de référence de ces fonctions.
Puis une fois votre programme my_prog compilé, il faut lui affecter les uid et gid de root, ainsi que le “set user or group id on execution” bit.
Sous root faire :

chown root my_prog
chgrp root my_prog
chmod a+s  my_prog

Maintenant que nous avons compris le principe, voici le code complet du programme que j’ai intitulé pk_suid_wrapper.
Vous pouvez constater que le nombre de lignes est ridicule... ( petit mais costaud )

Je ne commenterais pas plus avant le code, il est suffisamment simple pour être compris par toute personne  qui trouve un intérêt à cet article....
Sachez néanmoins qu’il gère toutes les sécurités nécessaires...

 
#include < stdio.h >
#include < stdlib.h >
#include < unistd.h >
#include < sys/types.h >
#include < sys/stat.h >

main(int argc, char**argv)
{
    int ok = 0;
    int uid,gid;
    struct stat statbuf;

    setuid(0);
    setgid(0);

    if (stat(argv[1],&statbuf))				{ fprintf(stderr,"cannot stat %s\n",argv[1]);			exit(-1); }
    if (statbuf.st_uid || statbuf.st_gid)	{ fprintf(stderr,"[%s] must be root root\n",argv[1]);	exit(-2); }

    if (stat(argv[2],&statbuf))				{ fprintf(stderr,"cannot stat %s\n",argv[2]);			exit(-1); }
    if (statbuf.st_uid || statbuf.st_gid)	{ fprintf(stderr,"[%s] must be root root\n",argv[2]);	exit(-2); }
    if (!(statbuf.st_mode & S_ISGID))		{ fprintf(stderr,"[%s] must be sgid root\n",argv[2]);	exit(-3); }
    if (!(statbuf.st_mode & S_ISUID))		{ fprintf(stderr,"[%s] must be suid root\n",argv[2]);	exit(-4); }

    for(;;)
    {
        if (!strcmp(argv[1],"/usr/bin/php"))	break;				// programme autorisé...

        fprintf(stderr,"setuid forbidden for [%s]!\n",argv[1]);
        exit(-5);
    }

    execv(argv[1],argv+1);
}

Pour pouvoir utiliser ce petit programme, il suffit de le compiler, puis d'exécuter (sous root) les commandes chown,chgrp,chmod décrites précédemment.

Puis, pour rendre votre script (ici php, mais vous pouvez adapter) exécutable en root :

  1. appliquez les mêmes commandes chown,chgrp,chmod à votre script.
  2. remplacez la première ligne du script
    #!/usr/bin/php
    par
    #!/le_path_du_fichier/pk_suid_wrapper /usr/bin/php

Veillez à ne rendre votre script modifiable que par des personnes autorisées !!!
Sinon, n’importe qui pourrait le modifier et exécuter n’importe quoi avec les permissions root sur votre système !

 

yakpro rulez!

Ce Site a été mis à jour le Mercredi 19 Janvier 2022 à 09:43:57