
PoC et correctif pour une vulnérabilité d'injection de commandes dans le gestionnaire d'URI yelp de Linux Mint 18.3-19.1. Démontre la cause racine, l'exploitation et la mitigation.
Les gestionnaires d'URI help://, ghelp:// et man:// sont définis dans le fichier /usr/share/applications/yelp.desktop, qui exécute /usr/local/bin/yelp via Exec=yelp %u à chaque fois que l'un de ces gestionnaires d'URI est invoqué.
Le fichier /usr/local/bin/yelp est un simple script Python qui analyse la requête entrante du gestionnaire d'URI. Ce script recherche d'abord les sous-chaînes "gnome-help" et "ubuntu-help", et s'il ne trouve aucune de ces sous-chaînes, il exécute /usr/local/bin/yelp sans mettre l'argument entre guillemets.
Contenu de /usr/local/bin/yelp :
#!/usr/bin/python
import os
import sys
if (len(sys.argv) > 1):
args = ' '.join(sys.argv[1:])
if ('gnome-help' in args) and not os.path.exists('/usr/share/help/C/gnome-help'):
os.system ("xdg-open http://www.linuxmint.com/documentation.php &")
elif ('ubuntu-help' in args) and not os.path.exists('/usr/share/help/C/ubuntu-help'):
os.system ("xdg-open http://www.linuxmint.com/documentation.php &")
else:
os.system ("/usr/bin/yelp %s" % args) # uh oh
else:
os.system ('/usr/bin/yelp')
L'exploitation a demandé un peu de créativité car Google Chrome encode en URI le caractère espace \x20, les accolades {}, le caractère plus +, le caractère accent grave `, et quelques autres. Comme ${IFS} ne fonctionnait pas, on a découvert que l'utilisation de $IFS$() fonctionne tout aussi bien, car l'instruction $() empêche la variable d'environnement $IFS de se concaténer avec d'autres caractères ASCII et de devenir accidentellement $IFSaddedword ou quelque chose d'approchant.
Le fichier yelp.patch modifie l'instruction vulnérable os.system ("/usr/bin/yelp %s" % args) en os.system ("/usr/bin/yelp %s" % quote(args)), ce qui utilise la méthode quote() de la bibliothèque shlex (https://docs.python.org/3/library/shlex.html#shlex.quote).
Soit patcher yelp, soit le supprimer.
sudo apt install patchsudo patch /usr/local/bin/yelp yelp.patchsudo rm /usr/share/applications/yelp.desktopsudo rm /usr/local/bin/yelp