Статья CUPS RCE уязвимость: полный разбор цепочки CVE-2024-47176 и эксплуатация print spooler

Запечатанный конверт с бордовой сургучной печатью на чёрном антистатическом коврике. Сквозь печать продет сетевой кабель с коннектором RJ45, от сломанного воска поднимается тонкая струйка дыма.


Десятки тысяч хостов с 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.
Финальный импакт: shell от имени пользователя lp на целевом хосте. Не root, но lp на большинстве дистрибутивов хватает для скачивания payload'ов (T1105, Ingress Tool Transfer), reverse shell'ов и дальнейшего продвижения. По данным Elastic Security Labs, пользователь lp во многих дефолтных конфигурациях имеет доступ к telnet - для печати он не нужен, а вот атакующему пригодится.

Четыре CVE - одна цепочка удалённого выполнения кода CUPS​

1783421577147.webp

Цепочка из трёх уязвимостей (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-летняя дыра в исполнении команд​

1783421608352.webp

Пакет: 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​

Полная цепочка атаки:
  1. Recon - сканирование UDP 631 или обнаружение через mDNS/DNS-SD в локальной сети
  2. Initial Access (T1190) - отправка UDP-пакета с URL вредоносного IPP-сервера
  3. Printer registration - cups-browsed запрашивает атрибуты, создаёт подставной принтер, генерирует PPD с вредоносными директивами
  4. Trigger - пользователь жертвы отправляет задание на печать на подставленный принтер (атакующий не может инициировать печать удалённо - ключевое ограничение)
  5. Execution (T1059.004) - foomatic-rip выполняет команду из FoomaticRIPCommandLine под учётной записью lp
  6. Post-exploitation - reverse shell, скачивание и запуск payload'а
Критический момент: без задания на печать RCE не происходит. По данным JFrog, на серверах, где никто никогда не печатает, 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 уязвимость не работает​

1783421660816.webp

Первоначальная оценка 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
Для MaxPatrol SIEM, KUMA, Splunk - базовые индикаторы для кастомных корреляционных правил: родительский процесс 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
Маргарителли рекомендует также блокировать DNS-SD: при недоступности UDP 631 напрямую атакующий может использовать zeroconf/mDNS спуфинг в локальной сети.

Эта цепочка 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. Сегодня.
 
Последнее редактирование модератором:
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

Похожие темы

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🧭 Навигатор · ИБ 2026
Не знаешь, какой трек твой?
5 направлений ИБ, реальные зарплаты и точка входа для каждого — в одном треде.
JuniorSenior+
100K → 600K+ ₽ /мес
Открыть навигатор →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab