Название проекта
Генератор эксплойта для CVE-2021-3156 sudo
Установка
- Установите зависимости: ./install.sh
- Запустите генератор эксплойта: ./run.sh
- Если версия sudo в системе уязвима, генерируется эксплойт для установленной версии
- Эксплойт генерируется в exploit.c, а бинарный файл — ./exploit
Требования
- gdb gcc make python3 python3-distro
- glibc с tcache
- В настоящее время поддерживаются ОС Ubuntu, Debian.
Протестировано
- Ubuntu 20.04.1
- Ubuntu 20.04.2
- Ubuntu 20.10
- Ubuntu 18.04.5
- Debian 10.7.0
Автор
Уязвимость
- sudo экранирует метасимволы в функции parse_args в main
- Затем в set_cmnd удаляются escape-символы, за которыми не следует пробел
- sudo предполагает, что parse_args является предусловием для set_cmnd.
- Проблема в том, что условия различаются в каждом парсере. Первый выполняется, если режим (MODE_RUN && MODE_SHELL). Второй выполняется, если режим (MODE_RUN | MODE_EDIT | MODE_CHECK) И (MODE_SHELL|MODE_LOGIN_SHELL)
- Существует способ не выполнять первый парсер, но выполнить второй: sudoedit -s
- set_cmnd вычисляет размер аргументов и создаёт chunk в куче для их объединения. Затем он копирует каждый аргумент до нулевого байта и переходит к следующему. Если входной аргумент заканчивается символом '\', set_cmnd пропускает escape-символ, копирует нулевой байт, но продолжает копировать следующий аргумент как часть того же самого. Это приводит к переполнению буфера в куче.
- Таким образом, если последний аргумент заканчивается на '\', set_cmnd переполняет буфер содержимым первой переменной окружения. Если эта переменная окружения заканчивается на '\', он продолжит копировать следующую.
Генератор эксплойта
- Используется метод 2, описанный в (https://packetstormsecurity.com/files/161160/Sudo-Heap-Based-Buffer-Overflow.html)
- sudo использует glibc nsswitch для чтения базы данных group после переполнения.
- nsswitch создаёт структуру данных service_table в куче со всеми базами данных и службами из nsswitch.conf.
- Службы group имеют тип struct service_user.
- Структура имеет поле name с именем службы.
- nsswitch динамически загружает библиотеку libnss_[имя_службы]_.so.2 в зависимости от конфигурации /etc/nsswitch.conf для каждой службы базы данных group.
- Указатель library должен быть перезаписан на NULL, чтобы избежать краха. Кроме того, это заставляет перезагрузить библиотеку в память, на этот раз локальную библиотеку с шеллкодом.
- Используется техника heap grooming или feng shui. Создаются «локальные» переменные окружения переменного размера для формирования раскладки кучи, позволяющей приблизить chunk, в который set_cmnd копирует аргументы, к цели — структуре service_user для group.
- Непосредственно перед вызовом malloc в set_cmnd просматривается tcache кучи, чтобы увидеть первые chunk'и, которые будут переработаны, и их размеры.
- Сортируются chunk'и, образующие базы данных и службы nsswitch. Они обходятся упорядоченно. Сохраняется адрес памяти целевого chunk'а и предыдущего.
- В bin tcache ищется chunk в этом диапазоне.
- Как только позиция chunk'а и его размер известны, генерируется эксплойт.
- Используется аргумент, заканчивающийся на '\' и нулевой байт точного размера, чтобы этот chunk был переработан.
- Создаются точные «локальные» переменные окружения для создания правильной раскладки.
- Перед этими «локальными» переменными генерируется переменная окружения необходимого размера, чтобы достичь целевой структуры.
- Целевая структура перезаписывается нулевыми байтами с помощью массивов строк с escape-символом '\', что приводит к записи нулевого байта в set_cmnd.
- Поле name структуры service_user перезаписывается на 'x/x', чтобы впоследствии загрузилась библиотека 'libnss_x/x.so.2'
- В библиотеке создаётся конструктор, который выполняет шеллкод.
- Поскольку sudo выполняется с suid-битом, полученная оболочка принадлежит root.
Лицензия
Этот проект распространяется под лицензией GNU GPL