Приветствую! Недавно работал по данным VM, также данную уязвимость активно эксплуатируют проукраинские хакерские группы.
Надеюсь, что мой материал будет полезен системным администраторам.
Также что-то взял отсюда:
Proxmox Auth Bypass CVE-2023-54391: Detect and Fix It
Представьте: у вас есть Proxmox VE 7.x, порт 8006 смотрит в сеть, а на хосте - root@pam. Не потому что вы так настроили, а потому что один параметр в API-запросе отключает проверку пароля. Это CVE-2023-54391 - pre-auth обход в libpve-access-control, который пускает неаутентифицированного атакующего под любым существующим включённым пользователем, включая root@pam.
И самое неприятное: CVE получил идентификатор 2023 года, но advisory вышел только 1 сентября 2026 года. Уязвимость закрыли в libpve-access-control 8.0.4 ещё в июле 2023-го, но окно экспозиции - три года. Все затронутые релизы уже EOL.
- Уязвимость: CVE-2023-54391, CVSS v3.1 9.8 CRITICAL, CWE-304.
- Затронуто: Proxmox VE 7.0-7.4 и начальный 8.0; libpve-access-control от 7.0-7 до 8.0.4 не включительно.
- Исправлено: libpve-access-control 8.0.4, июль 2023. Актуальные 8.x и 9.x не затронуты.
- Механика: при наличии параметра tfa-challenge пропускается проверка пароля. Значение параметра не валидировалось для пользователей без второго фактора.
- Последствия: тикет на root@pam - полный контроль над хостом, всеми VM/CT и кластерной ФС /etc/pve.
- Ремедиация: для 7.x - не патч, а апгрейд. Немедленно ограничить TCP 8006, применить vendor stop-gap, включить TFA, планировать переезд на 8.x/9.x.
Как работает байпас
Proxmox аутентифицирует через POST /api2/json/access/ticket. В нормальном two-factor flow клиент отправляет учётные данные, получает TFA-челлендж и повторно отправляет запрос с параметром tfa-challenge, внутри которого челлендж и второй фактор.
Логика обработчика: раз вторая нога flow уже доказала пароль, то само присутствие tfa-challenge считается доказательством, что парольный шаг пройден.
Багу в том, что значение параметра не проверялось для пользователя, у которого второй фактор не настроен. Достаточно передать параметр - проверка пароля пропускается, и вы получаете тикет на указанного пользователя. Без credentials, без предварительного доступа, без взаимодействия.
Два следствия:
- Тикет на root@pam - это тотальный контроль над хостом: все VM, все контейнеры, все диски, а через /etc/pve - кластерная файловая система, общая с другими нодами.
- Аккаунт с настроенным вторым фактором не уязвим, потому что идёт по пути валидации челленджа. Именно поэтому TFA здесь реально защищает - и именно поэтому на практике она защищает почти никого: TFA обычно стоит у людей, а сервисные аккаунты в /etc/pve/user.cfg про неё «забыли».
Апстрим закрыл дыру двумя коммитами в pve-access-control (032e7d6d и 0f3d14d6): теперь валидируется сам тикет челленджа, а не факт его наличия.
Кто под ударом
Формально:
- Proxmox VE 7.0-7.4;
- начальный релиз 8.0;
- libpve-access-control ниже 8.0.4.
Фактически - любой узел, который был доступен по 8006 из недоверенной сети и не обновлялся с июля 2023 года. Кластерность здесь не спасает: ноды дрейфуют по версиям, особенно добавленные позже или восстановленные из старого образа. Проверять нужно каждую ноду.
Проверка: четыре шага
Версия пакета
Код:
pveversion -v | grep libpve-access-control
Если версия ниже 8.0.4 - узел уязвим. Точка.
Через dpkg:
Код:
dpkg-query -W -f='${Package} ${Version} ${Status}\n' libpve-access-control
Кто может достучаться до login endpoint
pveproxy по умолчанию слушает 0.0.0.0:8006. Вопрос в том, что стоит перед ним. Проверяйте снаружи management-сети, не с доверенного jump host:
Код:
curl -sk -o /dev/null -w '%{http_code}\n' https://<node-ip>:8006/api2/json/version
Если management-интерфейс отвечает из general-purpose VLAN - это и есть предпосылка, которая превращает «плохо» в «уже случилось».
Логи доступа
pveproxy пишет каждый запрос в combined-формате. Смотрим, что било в ticket endpoint:
Код:
grep 'POST /api2/json/access/ticket' /var/log/pveproxy/access.log*
На здоровом кластере клиенты - это админские рабочие станции и хосты автоматизации. Всё остальное требует объяснения.
Коррелируем с успешными аутентификациями:
Код:
journalctl -u pvedaemon --since '90 days ago' | grep 'successful auth'
Ищем успешные входы - особенно root@pam - с адресов, которых нет в обычном админском паттерне, и успехи без обычной authentication chatter.
Важно: retention, скорее всего, вас победит. Три года - это далеко за пределами стандартной ротации. Отсутствие следов здесь не равно отсутствию компрометации.
База пользователей
Проверьте каждого включённого пользователя и каждый API-токен. Атакующий, получивший тикет root@pam, не обязан оставлять следы, но persistence дёшев, и люди им пользуются. Отдельно пройдитесь по инвентарю токенов: что живо, что забыто, что выдано «на время».
Ремедиация
Если вы на 8.x или 9.x
С высокой вероятностью вы уже пропатчены, потому что 8.0.4 вышел в июле 2023. Но лучше подтвердить, чем предполагать:
Код:
apt update && apt full-upgrade
pveversion -v | grep libpve-access-control
Если вы на 7.x
Варианта, который заканчивается тем, что вы остаётесь на 7.x, нет. Линия ушла в EOL в июле 2024, 8.x - 31 августа 2026. Proxmox выпустил stop-gap, который валидирует tfa-challenge для затронутых EOL-инсталляций. Его нужно применить сегодня, но воспринимать как покупку окна на обслуживание, а не как фикс.
Порядок действий:
- Немедленно ограничить TCP 8006 management VLAN или VPN. Это контроль, который реально останавливает неаутентифицированного интернет-атакующего, пока вы планируете.
- Применить vendor stop-gap из ветки Proxmox security advisories.
- Включить TFA на всех аккаунтах, за которыми стоит человек. Это защищает именно от такого класса ошибок.
- Планировать апгрейд. С 7.x до актуальной версии - два прыжка через 8.x.
Если узел был доступен из интернета без патча
Относитесь как к компрометации:
- ротация root@pam и всех локальных паролей;
- ротация всех API-токенов;
- ротация SSH host keys и authorized_keys;
- ротация всех credentials, к которым имели доступ VM и контейнеры на хосте;
- проверка на «скучный» persistence: неожиданные пользователи в /etc/pve/user.cfg, cron-записи, изменённые hook-скрипты.
Харденинг login endpoint
Патч закрывает конкретный CVE. Но management API будет и дальше притягивать баги аутентификации, поэтому имеет смысл в то же окно сузить периметр навсегда.
Привязать к management-интерфейсу
pveproxy по умолчанию слушает все интерфейсы. Если у ноды есть выделенный management NIC, укажите это в /etc/default/pveproxy:
И ограничьте, кто может говорить с ним:
Код:
ALLOW_FROM="10.20.0.0/24,10.20.5.7"
DENY_FROM="all"
POLICY="allow"
Перезапуск:
Код:
systemctl restart pveproxy
ss -lntp | grep 8006
Держите консольную сессию открытой, пока делаете это, чтобы не отрезать себя.
Включить второй фактор на уровне realm
Эта бага особенно щадила аккаунты с настроенным вторым фактором. Realm-wide TFA enforcement закрыл бы её целиком. Настраивается в Datacenter -> Permissions -> Two Factor. Отдельно аудит: у кого TFA всё ещё нет. Список обычно длиннее, чем ожидаешь, и почти весь состоит из сервисных аккаунтов.
Rate-limit на перебор
Proxmox firewall и fail2ban вместе превращают credential-атаки на 8006 в шум, а не в рабочую поверхность. Нужен jail, который читает authentication failures от pveproxy.
Ни один из этих шагов не остановит запрос с валидным на вид тикетом из разрешённого источника. Но все они сокращают множество тех, кто вообще может попробовать.
Честно о сигналах угрозы
Сигналы по этому CVE указывают в разные стороны.
За срочность:
- неаутентифицированный обход до root на management API;
- CVSS 9.8;
- включение в VulnCheck KEV;
- публичные технические разборы;
- vendor advisory, который выпустил stop-gap для EOL-релизов.
Против паники:
- EPSS около 0.5% на 39-м перцентиле в начале сентября;
- публичный PoC в основных CVE-базах не каталогизирован.
Это скромный predicted-exploitation сигнал для 9.8. Объяснение простое: EPSS моделирует exploitation volume в интернете, а management-интерфейсы Proxmox - правильно - обычно не торчат в интернет. Популяция маленькая, но последствие на хост - тотальное.
Для конкретного админа это не меняет ремедиацию: она дешёвая, а с 7.x всё равно надо было уходить.
Чек-лист для админа
Код:
[ ] Проверить pveversion -v | grep libpve-access-control на каждой ноде.
[ ] Если версия < 8.0.4 - считать узел уязвимым.
[ ] Проверить, кто отвечает на 8006 снаружи management-сети.
[ ] Проверить grep 'POST /api2/json/access/ticket' /var/log/pveproxy/access.log*.
[ ] Проверить journalctl -u pvedaemon --since '90 days ago' | grep 'successful auth'.
[ ] Проверить /etc/pve/user.cfg на лишних пользователей и токены.
[ ] Ограничить TCP 8006 management VLAN/VPN - сегодня.
[ ] Применить vendor stop-gap для 7.x.
[ ] Включить TFA на всех «человеческих» аккаунтах.
[ ] Запланировать апгрейд 7.x -> 8.x -> 9.x.
[ ] При подозрении на компрометацию - ротировать всё.
Итог
Запустите:
Код:
pveversion -v | grep libpve-access-control
на каждой ноде. Если версия ниже 8.0.4, этот узел с 2023 года принимал беспарольные логины как root@pam от любого, кто мог достучаться до порта 8006.
Актуальные 8.x и 9.x в порядке. Всё, что осталось на 7.x, требует сегодня ограничить API-порт, на этой неделе применить stop-gap и поставить в календарь настоящий апгрейд. Потому что следующее advisory против EOL-релиза может прийти уже без stop-gap.
Комментарии
1