
PoC y parche para una vulnerabilidad de inyección de comandos en el manejador de URI de yelp en Linux Mint 18.3-19.1. Demuestra la causa raíz, la explotación y la mitigación.
Los manejadores de URI help://, ghelp:// y man:// están definidos en el archivo /usr/share/applications/yelp.desktop, que ejecutará /usr/local/bin/yelp mediante Exec=yelp %u cada vez que se invoque uno de esos manejadores de URI.
El archivo /usr/local/bin/yelp es un simple script de Python que analiza la solicitud entrante del manejador de URI. Este script primero busca las subcadenas "gnome-help" y "ubuntu-help", y si no encuentra ninguna de esas subcadenas, entonces ejecutará /usr/local/bin/yelp sin encerrar el argumento entre comillas.
Contenido 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')
La explotación requirió un poco de creatividad, ya que Google Chrome codifica en la URI el carácter de espacio \x20, las llaves {}, el signo más +, el carácter de comilla invertida `, y algunos otros. Dado que ${IFS} no funcionaba, se descubrió que usar $IFS$() funciona igual de bien, ya que la sentencia $() evita que la variable de entorno $IFS se concatene con otros caracteres ASCII y accidentalmente se convierta en $IFSaddedword o algo así.
El archivo yelp.patch modifica la sentencia vulnerable de os.system ("/usr/bin/yelp %s" % args) a os.system ("/usr/bin/yelp %s" % quote(args)), que aprovecha el método quote() de la librería shlex (https://docs.python.org/3/library/shlex.html#shlex.quote).
O bien parchea yelp, o elimínalo.
sudo apt install patchsudo patch /usr/local/bin/yelp yelp.patchsudo rm /usr/share/applications/yelp.desktopsudo rm /usr/local/bin/yelp