Уязвимости в утилите Needrestart, позволяющие получить Root-доступ в Ubuntu Server

Компания Qualys выявила три уязвимости в утилите needrestart, предназначенной для перезапуска фоновых процессов после обновления используемых данными процессами библиотек. Начиная с Ubuntu 21.04 утилита needrestart включена в состав базового окружения Ubuntu Server, в котором запускается с правами root в конце каждой транзакции пакетного менеджера APT, сканирует запущенные процессы и перезапускает те их них, что связанны с файлами, изменившимися после обновления пакетов. Выявленные уязвимости позволяют локальному непривилегированному пользователю получить права root в Ubuntu Server в конфигурации по умолчанию.

Уязвимости присутствуют в needrestart начиная с версии 0.8 (2014 год) и устранены в выпуске needrestart 3.8. Проблемы также уже исправлены в дистрибутивах Debian и Ubuntu. В качестве обходного пути блокирования эксплуатации уязвимости можно отключить сканирование интерпретаторов, указав в файле конфигурации /etc/needrestart/needrestart.conf параметр “$nrconf{interpscan} = 0”.

Уязвимости присутствуют в коде с реализацией режима определения обновления скриптов, запущенных с использованием интерпретаторов. Выявленные проблемы:

  • CVE-2024-48990 – локальный пользователь может добиться выполнения кода с правами root через создание условий для запуска Python-интерпретатора с выставленной атакующим переменной окружения PYTHONPATH. Кроме использования Python атака также может быть проведена (CVE-2024-48992) через запуск интерпретатора Ruby с переменной окружения RUBYLIB.

    Уязвимости вызваны тем, что в процессе перезапуска изменившегося скрипта утилита needrestart выставляет переменную окружения PYTHONPATH на основе содержимого файла /proc/pid/environ. Соответственно, атакующий может дождаться активности, связанной с работой пакетного менеджера APT, и симулировать изменение своего скрипта и установить для него переменную окружения PYTHONPATH, которая также будет применена при запуске встроенного в needrestart Python-кода (“import sysnprint(sys.path)”), выполняемого с правами root.

    Например, для эксплуатации уязвимости можно запустить постоянно висящий в памяти Python-процесс, выставив для него переменную окружения “PYTHONPATH=/home/test”, и разместить в разделяемую библиотеку “/home/test/importlib/__init__.so”, которая будет выполнена при выполнении привилегированного Python-кода в needrestart.

  • CVE-2024-48991 – локальный пользователь может добиться выполнения кода с правами root через инициирование состояния гонки (race condition), в результате которого needrestart запустит фиктивный интерпретатор Python, подставленный атакующим, вместо системного интерпретатора Python. Суть уязвимость похода на вышеотмеченную проблему, разница только в том, что needrestart определяет имя процесса Python (например, /usr/bin/python3) через чтение “/proc/pid/exe”.

    Для эксплуатации уязвимости можно создать процесс /home/test/race, который дождётся пока needrestart начнёт читать содержимое /proc/pid/exe при помощи inotify и сразу запустит через функцию execve системный интерпретатор Python. Так как needrestart не выполняет проверку настоящий ли это Python, то он посчитает, что /home/test/race и есть интерпретатор Python и запустит его для своего кода.

  • CVE-2024-11003 – локальный пользователь может добиться выполнения произвольных shell-команд с правами root через создание условий для открытия в needrestart имён файлов в формате “команда|”, обработка которого в функции open() в Perl приведёт к запуску команды. Фактически уязвимость проявляется в Perl-модуле ScanDeps (CVE-2024-10224), но вызвана передачей в этот модуль внешних параметров без должной проверки.

    Атака может быть осуществлена через запуск Perl-скрипта с символом “|” в имени, например, “/home/test/perl|”. В процессе выполнения функции scan_deps() в needrestart данный файл будет открыт в функции open(), которая обработает символ “|” как флаг для запуска программы “/home/test/perl”.

Release. Ссылка here.