Re: Exécuter un bash script depuis un script PHP

Top Page

Reply to this message
Author: p.karatchentzeff
Date:  
CC: guilde
Old-Topics: Re: Exécute r un bash script depuis un script PHP
New-Topics: Re: Exécute r un bash script depuis un script PHP
Subject: Re: Exécuter un bash script depuis un script PHP
Selon Edgar Bonet <guilde@???>:

> Le vendredi 26 septembre, p.karatchentzeff@??? a écrit :
> > > Si ton script commence par "#!/bin/sh" et qu'il est exécutable, tu n'as
> > > pas besoin d'invoquer /bin/sh dans l'appel de system. Tu peux écrire
> > >
> > >     system("/home/jabber/cmd.sh $argumentsh");

> >
> > Si l'on ne vérifie pas le PATH *avant* de lancer ta commande, le
> > bin/sh peut-être n'importe quoi...
>
> bin/sh peut être n'importe quoi, mais si je ne m'abuse, /bin/sh (avec un
> / au début) ne peut être que /bin/sh. Donc si le script commence par
> "#!/bin/sh" je ne vois pas où est le problème. Et s'il commence par
> "#!bin/sh" (drôle d'idée) ça ne marche pas.
>


Non *si* le script est setuid, on peut détourner l'appel au shell entre le
moment où on l'appelle et le moment où le noyau envoie réellement la requête au
shell. Lire la partie setuid dans la doc de Perl... On peut contourner cela en
enrobant le script Perl dans un programme C je crois...

> > et donc on peut ainsi ouvrir une faille dans le système.
>
> Où ça ? C'est la même personne qui écrit le script shell et le script
> php qui appelle le script shell. Tu penses au cas où l'attaquant
> pourrait modifier les variables d'environnement du serveur ?
>


Oui. Ou les données qui vont autours (genre script CGI).

> > Sous Perl, on peut lancer l'interpréteur dans un mode
> > « d'entachement » qui vérifie ce genre de problème...
>
> $ perl -Te 'system "/home/edgar/cmd.sh"'
> Insecure $ENV{PATH} while running with -T switch at -e line 1.
> $ perl -Te 'system "/bin/sh /home/edgar/cmd.sh"'
> Insecure $ENV{PATH} while running with -T switch at -e line 1.
>
> Visiblement ce n'est pas /bin/sh qui froisse perl -T. À mon avis il ne
> regarde même pas le paramètre de system(), il sait juste que system()
> peut lancer un shell et il n'aime pas lancer un shell avec un PATH non
> contrôlé. C'est pas qu'il a peur de lancer un faux shell, c'est qu'il a
> peur de ce que le vrai shell va faire.


Oui et non : ici, il râle parce que le programme n'a pas testé le path avant
mais le trou de sécurité est autant du fait de l'appel au shell que de la
possiblité d'appeler une sous-commande du système non contrôlée :

Ensuite, le problème est expliqué dans man perlsec :

           system "echo $arg";         # Insecure
           system "/bin/echo", $arg;   # Allowed but considered insecure
                                       # (Perl doesn't know about /bin/echo)
           exec "sh", '-c', $arg;      # Considered secure, alas!


dans le premier cas, l'exécution aveugle de $arg peut-être catastrophique et
dans le second cas, le /bin/echo peut être n'importe quoi. Dans le dernier cas,
c'est Perl qui maîtrise ce qu'il exécute, avec les arguments et les données
(mais cela n'empêche pas de tester la donnée car si $arg="\rm -rf"...).

Il en va de même avec /bin/sh.

La solution est de tester le path :

           $ENV{'PATH'} = '/bin:/usr/bin';
           delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
           $path = $ENV{'PATH'};       # $path now NOT tainted
           system "echo $data";        # Is secure now!


et maintenant on est sûr que echo est bien celui du système et $data est à
vérifier par le programmeur (et peut être soutenu par Perl en activant le pragma
vérifiant l'intégrité des données (qui chroote le programme pour éviter les
effets de bord désastreux)).

Bon, bien sûr, tout cela est dans le mode parano mais c'est un mode à activer
lorsque l'on fait exécuter un code qui reçoit des données sur un serveur par des
gens (connus et inconnus).

PK