sh vs bash
J’écris cet article car j’ai constaté à deux reprises un comportement que je ne comprenais pas. L’appel système
execve("/bin/sh", NULL, NULL)
me lançait un terminal bash
au lieu de sh
. Comme j’étais en phase d’exploitation avec une élévation de privilèges, et comme bash
drop les droits par défault, je me retrouvais avec un shell qui n’avait plus les droits du binaire.
Voici alors un petit post qui me servira plus de rappel à moi-même qu’autre chose. Les deux ressources citées en fin d’article vous permettront d’aller voir un peu plus loin.
sh
est un langage de programmation décrit par le standard POSIX. Il possède plusieurs implémentations telles que dash
, ksh
etc.
Ainsi, dans la plupart des systèmes d’exploitation, sh
n’étant pas une implémentation, /bin/sh
est un lien symbolique vers une implémentation, souvent /bin/bash
.
Dans mon système d’exploitation actuel, je peux le voir
/bin/sh -> bash*
bash
est donc une implémentation de sh
, cependant beaucoup de modules/extensions y ont été ajoutés. Lorsqu’on fait un appel à /bin/bash
, nous avons l’implémentation de sh
avec tout un tas d’extensions.
Cependant, le binaire /bin/bash
a implémenté une vérification sur argv[0]
(contenant la ligne de commande qui a appelé le binaire). Si le binaire a été appelé via /bin/sh
, alors /bin/bash
va essayer d’imiter le comportement des versions historiques de sh
. Les extensions de démarrage de bash
ne seront pas chargées, notamment celle qui fait perdre l’élévation des droits suite à une exécution d’un binaire possédant le bit SUID
.
Voici quelques exemples
# Appel via sh
$ /bin/sh
sh-3.4 $
# Appel via bash
$ /bin/bash
bash-4.3 $
# Appel système execve("/bin/sh", NULL, NULL)
bash-4.3 $
# Appel système execve("/bin/sh", ["/bin/sh"], NULL)
sh-3.4 $
Vous voyez bien avec ces différents exemples que lorsque le binaire bash
est exécuté, si jamais argv[0]
contient le chemin vers sh
alors nous avons une imitation du comportement historique de sh
qui est exécutée. Dans le cas contraire, c’est bien le binaire bash
et toutes ses extensions qui est exécuté.
Voilà pourquoi je perdais les droits pendant mes exploitations. Il me suffit alors de faire en sorte que le deuxième argument de execve
pointe vers un tableau contenant une chaîne de caractères : "/bin/sh"
.
Références