## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-LMOL-CVE-2021-3156
# Название проекта
Генератор эксплойта для CVE-2021-3156 sudo
## Установка
1. Установите зависимости: ./install.sh
2. Запустите генератор эксплойта: ./run.sh
3. Если версия sudo в системе уязвима, генерируется эксплойт для установленной версии
4. Эксплойт генерируется в exploit.c, а бинарный файл — ./exploit
## Требования
1. gdb gcc make python3 python3-distro
2. glibc с tcache
3. В настоящее время поддерживаются ОС Ubuntu, Debian.
## Протестировано
* Ubuntu 20.04.1
* Ubuntu 20.04.2
* Ubuntu 20.10
* Ubuntu 18.04.5
* Debian 10.7.0
## Автор
* **Luis Molina Garzón** \- (https://gitlab.iesvirgendelcarmen.com/luis/CVE-2021-3156/)
* **Qualys Research Team.** (https://blog.qualys.com/vulnerabilities-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit)
## Уязвимость
* 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