Десятки тысяч хостов с CUPS торчали в интернет на момент раскрытия CVE-2024-47176 - значительная часть из них принимала подключения без аутентификации на UDP 631. Когда я воспроизводил эту цепочку в Docker-лабе с cups-browsed 2.0.1, от первого UDP-пакета до выполнения команды через foomatic-rip прошло меньше двух минут. Дефолтная конфигурация, ни одного ручного действия кроме отправки задания на печать. Два. Минуты.
Три CVE (CVE-2024-47076, CVE-2024-47175, CVE-2024-47176), раскрытые Симоне Маргарителли (@evilsocket) в сентябре 2024, превращают "безобидный" демон автообнаружения принтеров в полноценный вектор initial access на GNU/Linux, BSD и Solaris. Четвёртый идентификатор - CVE-2024-47177 - отклонён (REJECTED) NVD как дубликат первых трёх.
Бизнес-логика атаки: зачем атакующему print spooler
[Применимо: внутренний пентест, внешний пентест при доступном UDP 631]Серверы печати - одни из самых забытых компонентов инфраструктуры. Патчи для CUPS откладываются, потому что "принтеры и так работают". На внутренних проектах я вижу это раз за разом: print server без EDR, без обновлений, с конфигом из коробки. Идеальные условия.
Что даёт цепочка атакующему:
- Initial access (T1190, Exploit Public-Facing Application) - cups-browsed принимает UDP-пакеты на порту 631 без аутентификации. Из внешней сети - прямой путь на хост. Из внутренней - mDNS/DNS-SD позволяют спуфить принтер и обойти необходимость прямого доступа к порту.
- Execution (T1059.004, Unix Shell) - foomatic-rip выполняет shell-команды, указанные в PPD-файле. Это документированная функциональность, унаследованная аж с 2011 года.
- Lateral movement (T1210, Exploitation of Remote Services) - скомпрометированный print server с сетевым доступом к другим подсетям становится pivot point.
lp на целевом хосте. Не root, но lp на большинстве дистрибутивов хватает для скачивания payload'ов (T1105, Ingress Tool Transfer), reverse shell'ов и дальнейшего продвижения. По данным Elastic Security Labs, пользователь lp во многих дефолтных конфигурациях имеет доступ к telnet - для печати он не нужен, а вот атакующему пригодится.Четыре CVE - одна цепочка удалённого выполнения кода CUPS
Цепочка из трёх уязвимостей (CVE-2024-47177 отклонён NVD как дубликат). Ни одна по отдельности не даёт RCE - работает только комбинация. Каждая закрывает зазор между "получил сетевой доступ" и "выполнил код".
CVE-2024-47176: cups-browsed принимает пакеты от кого угодно
Пакет: cups-browsed <= 2.0.1. CVSS: 5.3 Medium по NVD.Демон cups-browsed привязывается к
UDP INADDR_ANY:631 - слушает на всех интерфейсах. Любой UDP-пакет с любого IP запускает Get-Printer-Attributes IPP-запрос к URL из пакета. Один пакет - и cups-browsed сам подключается к IPP-серверу атакующего, автоматически регистрирует подставной принтер. Красота.Работает если: cups-browsed запущен,
BrowseRemoteProtocols в /etc/cups/cups-browsed.conf включает значение cups, UDP 631 доступен атакующему.Не работает если: cups-browsed остановлен (на RHEL по умолчанию отключён, по данным Red Hat), порт слушает только loopback (по данным JFrog, Debian 12, RHEL 8, Ubuntu Desktop 22.04/24.04 при чистой установке слушают только 127.0.0.1 и ::1).
Проверка на целевом хосте:
sudo systemctl status cups-browsed. Если active (running) - демон работает и потенциально уязвим. Далее: ss -ulnp | grep 631 покажет, на каких адресах слушает.CVE-2024-47076 и CVE-2024-47175: данные атакующего без фильтрации
Пакеты: libcupsfilters <= 2.1b1, libppd <= 2.1b1. CVSS: 8.6 High каждая по NVD (CVSS:3.1).Когда cups-browsed подключается к IPP-серверу атакующего, функция
cfGetPrinterAttributes5 в libcupsfilters принимает IPP-атрибуты без валидации (CVE-2024-47076). Функция ppdCreatePPDFromIPP2 в libppd записывает эти атрибуты во временный PPD-файл без экранирования (CVE-2024-47175).По анализу JFrog, причина - design flaw в IPP-протоколе: атрибуты от принтера считаются доверенными. PPD описывает свойства принтера для CUPS: какие фильтры вызывать и какие команды выполнять при обработке задания. Результат: атакующий контролирует содержимое PPD-файла на целевой системе. Может инжектировать директиву
FoomaticRIPCommandLine с произвольной командой и директивы cupsFilter2, указывающие на foomatic-rip как обработчик.CVE-2024-47177 (REJECTED): foomatic-rip - 13-летняя дыра в исполнении команд
Пакет: cups-filters <= 2.0.1. Первоначальная оценка CVSS: 9.9 (до отклонения CVE). Статус NVD: REJECTED - признан дубликатом CVE-2024-47076, CVE-2024-47175 и CVE-2024-47176.
Фильтр foomatic-rip выполняет команды из директивы
FoomaticRIPCommandLine в PPD-файле. Аналогичный механизм эксплуатировался с 2011 года - HPLIP foomatic-rip-hplip (CVE-2011-2697) и Foomatic foomatic-filters (CVE-2011-2964), как указывает Elastic Security Labs. Исправления вошли в те отдельные пакеты, но не были перенесены в cups-filters/foomatic-rip. Причина, по данным JFrog: полное исправление ломает обратную совместимость с большинством существующих драйверов принтеров. Тринадцать лет - и баг всё ещё тут.Директива
cupsFilter2 в PPD указывает исполняемый файл из /usr/lib/cups/filter/, который вызывается при обработке задания на печать. foomatic-rip - один из таких фильтров, и он по архитектуре предполагает выполнение shell-команд для конвертации документов.Место в kill chain и предусловия эксплуатации print spooler
Полная цепочка атаки:- Recon - сканирование UDP 631 или обнаружение через mDNS/DNS-SD в локальной сети
- Initial Access (T1190) - отправка UDP-пакета с URL вредоносного IPP-сервера
- Printer registration - cups-browsed запрашивает атрибуты, создаёт подставной принтер, генерирует PPD с вредоносными директивами
- Trigger - пользователь жертвы отправляет задание на печать на подставленный принтер (атакующий не может инициировать печать удалённо - ключевое ограничение)
- Execution (T1059.004) - foomatic-rip выполняет команду из
FoomaticRIPCommandLineпод учётной записьюlp - Post-exploitation - reverse shell, скачивание и запуск payload'а
Практическая эксплуатация CUPS RCE уязвимости
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
покажет все анонсируемые IPP-принтеры в локальной сети без сканирования портов. Быстрее и тише, чем nmap.
Воспроизведение цепочки
Elastic Security Labs использовали PoC "cupshax" для тестирования. PoC создаёт фейковый IPP-сервис через mDNS/ZeroConf, анонсирует подставной принтер. При подключении уязвимого cups-browsed возвращает IPP-атрибуты с вредоносной директивой.Пример вредоносного PPD-фрагмента (из публикации opennet.ru):
Код:
*FoomaticRIPCommandLine: "echo 1 > /tmp/I_AM_VULNERABLE"
*cupsFilter2: "application/pdf application/vnd.cups-postscript 0 foomatic-rip"
cupsFilter2 указывает CUPS вызвать foomatic-rip при обработке PDF. FoomaticRIPCommandLine содержит команду для выполнения. В реальной атаке echo 1 > /tmp/I_AM_VULNERABLE заменяется на reverse shell или загрузчик.При тестировании Elastic зафиксировали:
- Команды выполняются от имени пользователя и группы
lp- дефолтная учётная запись для печати на Linux с CUPS - Интерактивные reverse shell'ы напрямую не поддерживаются - у
lpнет login shell, но с дополнительными техниками (Elastic называет это «creative tactics») обратную оболочку получить можно - В телеметрии родительский процесс - foomatic-rip, порождающий shell. Аномальное поведение и надёжный индикатор компрометации
- Файлы, создаваемые эксплоитом, принадлежат
lp- запись в/tmp/тривиально детектируется
Ограничения: когда CUPS RCE уязвимость не работает
Первоначальная оценка CVSS 9.9 (присвоена до отклонения CVE-2024-47177) выглядела пугающе. Реальная эксплуатируемость - ниже. Red Hat пересмотрела оценку до 6.1 (Important). JFrog присвоила Medium severity. И вот почему:
| Фактор | Влияние |
|---|---|
| cups-browsed выключен | Атака невозможна - нет входной точки |
| UDP 631 только loopback | Только локальная атака |
| Задание на печать обязательно | Атакующий не может запустить печать удалённо |
| AppArmor / SELinux | Ограничивают действия lp - shell может не запуститься |
| Права lp | Не root; payload зависит от конфигурации |
| Сервер без пользователей | Нет печати - payload не активируется |
По данным JFrog, Debian 12, RHEL 8, Ubuntu 16.04/22.04/24.04 Desktop при чистой установке слушают только на loopback. Ubuntu Server не ставит CUPS по умолчанию.
Для внутреннего пентеста ситуация другая: если cups-browsed настроен для auto-discovery в корпоративной сети и сотрудники регулярно печатают - цепочка работает. Администраторы, включающие
BrowseRemoteProtocols cups для удобства, создают именно те условия, которые нужны атакующему. CrowdStrike Falcon и SentinelOne детектируют аномальный запуск shell из foomatic-rip на уровне EDR-агента, но только если агент установлен на print server. А серверы печати нередко остаются без EDR-покрытия - я это вижу на каждом втором проекте.Детектирование эксплуатации CUPS print spooler
Elastic Security Labs выпустили OOTB-правила детектирования, доступные начиная с Prebuilt Security Detection Rules версий 8.12.23+, 8.13.18+, 8.14.12+, 8.15.6+:- cupsd or foomatic-rip shell execution - запуск shell из процесса cupsd или foomatic-rip
- Printer user (lp) shell execution - shell от имени пользователя lp
- Network connection by CUPS foomatic-rip child - исходящие сетевые подключения от дочерних процессов foomatic-rip (индикатор загрузки payload'а)
- File creation by CUPS foomatic-rip child - создание файлов дочерними процессами foomatic-rip
foomatic-rip порождает bash, sh или dash; пользователь lp создаёт исполняемые файлы или файлы в нетипичных путях (/dev/shm/, домашние каталоги) в сочетании с родительским процессом foomatic-rip -> shell; исходящее сетевое подключение от дочернего процесса foomatic-rip. Входящий UDP-пакет на порт 631 с внешнего адреса - повод для алерта в любом stateful firewall.Если cups-browsed не нужен для работы - отключение остаётся самой эффективной мерой:
Bash:
sudo systemctl stop cups-browsed
sudo systemctl disable cups-browsed
# Дополнительно: блокировка UDP 631 на периметре
sudo ufw deny in 631/udp
Эта цепочка CUPS RCE уязвимостей - не разовый инцидент. В 2026 году появились CVE-2026-34990 (NVD CVSS 4.0: 5.0 Medium, CWE-287; Red Hat CVSS 3.1: 5.2, CWE-73 - локальный непривилегированный пользователь может заставить cupsd аутентифицироваться к IPP-сервису атакующего) и CVE-2026-34980 (NVD CVSS 4.0: 6.1 Medium, AV:A, CWE-20; Red Hat CVSS 3.1: 6.4, CWE-78 - инъекция newline в атрибуте page-border позволяет неаутентифицированному клиенту в той же сети внедрить директиву в PPD shared PostScript-очереди). По данным CISA-ADP, для обоих существуют PoC, решение SSVC - Track (следить, готовить патч). Red Hat пометила CVE-2026-34980 как Affected для RHEL 10, а CVE-2026-34990 - как Fix deferred. При этом Red Hat использует собственные оценки CVSS: 5.2 (CWE-73) для CVE-2026-34990 и 6.4 (CWE-78) для CVE-2026-34980, что отличается от NVD (CWE-287 и CWE-20 соответственно).
Каждый год в CUPS находят новый путь к выполнению команд, и корневая причина не меняется: foomatic-rip вызывает shell по дизайну, IPP-атрибуты по дизайну считаются доверенными, PPD по дизайну описывает исполняемые фильтры. Пока эта архитектура живёт - CVE-2024-47177 и его наследники будут появляться. На внутренних engagement'ах я проверяю cups-browsed в первые 15 минут - это низковисящий фрукт с high-impact результатом, если условия совпадают. Но большинство команд защиты не вводят одну строку
systemctl disable cups-browsed, пока не случится инцидент. Серверы печати годами сидят без EDR, без обновлений, с BrowseRemoteProtocols cups в конфиге - и администраторы искренне удивляются, когда из-за "принтера" утекает lateral movement в продуктивный сегмент. Проблема не техническая. Print spooler не воспринимается как attack surface - ни заказчиками, ни SOC-аналитиками. Если у вас CUPS в инфраструктуре и cups-browsed запущен - отключите его сегодня. Не завтра, не после согласования change request. Сегодня.
Последнее редактирование модератором: