
PoC и патч для уязвимости внедрения команд в обработчике URI yelp в Linux Mint 18.3–19.1. Демонстрирует первопричину, эксплуатацию и меры по смягчению.
Обработчики URI help://, ghelp:// и man:// определены в файле /usr/share/applications/yelp.desktop, который выполняет /usr/local/bin/yelp через Exec=yelp %u всякий раз, когда вызывается один из этих обработчиков URI.
Файл /usr/local/bin/yelp — это простой скрипт на Python, который разбирает входящий запрос обработчика URI. Этот скрипт сначала ищет подстроки "gnome-help" и "ubuntu-help", и если не находит ни одной из этих подстрок, то выполняет /usr/local/bin/yelp без заключения аргумента в кавычки.
Содержимое /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')
Для эксплуатации потребовалось немного творчества, поскольку Google Chrome кодирует в URI пробел \x20, фигурные скобки {}, символ плюса +, символ обратной кавычки ` и некоторые другие. Поскольку ${IFS} не работал, было обнаружено, что использование $IFS$() работает так же хорошо, так как конструкция $() предотвращает объединение переменной окружения $IFS с другими ASCII-символами и случайное превращение в $IFSaddedword или что-то подобное.
Файл yelp.patch изменяет уязвимую строку с os.system ("/usr/bin/yelp %s" % args) на os.system ("/usr/bin/yelp %s" % quote(args)), используя метод quote() из библиотеки shlex (https://docs.python.org/3/library/shlex.html#shlex.quote).
Либо пропатчите yelp, либо удалите его.
sudo apt install patchsudo patch /usr/local/bin/yelp yelp.patchsudo rm /usr/share/applications/yelp.desktopsudo rm /usr/local/bin/yelp