EPSS score 0.9998 (99.98% вероятность эксплуатации в течение 30 дней), percentile 99.98% - CVE-2024-4879 в ServiceNow сидит в top 0.02% среди всех зарегистрированных уязвимостей по данным FIRST.org. Обе критических pre-auth уязвимости - CVE-2024-4879 (CVSS 9.3) и CVE-2024-5217 (CVSS 9.2) - добавлены в каталог CISA KEV как активно эксплуатируемые с 29 июля 2024 года. inthewild.io тоже фиксирует эксплуатацию обеих CVE (дата совпадает с добавлением в KEV - 29 июля 2024, что скорее указывает на KEV как первоисточник, а не на независимое подтверждение).
На внешних пентестах enterprise-инфраструктуры ServiceNow-инстансы попадаются почти в каждом скоупе. И далеко не все из них пропатчены - особенно self-hosted. Здесь я разберу, как устроены pre-auth цепочки эксплуатации ServiceNow на уровне архитектуры: от Jelly Template Injection до выполнения произвольного кода через
javascript:-evaluation в GlideRecord. С конкретными CVE, CWE, PoC-ссылками и привязкой к kill chain.Бизнес-логика атаки: зачем атакующему ITSM-платформа
ServiceNow - это не тикет-система с красивым фантиком. Now Platform управляет IT-операциями, HR-процессами и активами одновременно. Вот что лежит в типичном инстансе:- IT-тикеты с вложениями - скриншоты сетевой топологии, данные об инцидентах, внутренние IP-адреса, конфигурации
- Credentials в workflow'ах - API-токены, пароли от интеграций, service account credentials, данные support-кейсов
- HR-записи - должности, контакты, оргструктура
- CMDB - полная карта инфраструктуры: серверы, сетевое оборудование, зависимости между сервисами
- SSO-конфигурации и SAML-сертификаты для интеграции с корпоративным IdP
Архитектура ServiceNow и pre-auth attack surface
[Применимо: внешний пентест, black box, hosted и self-hosted ServiceNow Utah / Vancouver / Washington DC]
Чтобы понять, откуда берутся pre-auth RCE в корпоративных платформах класса ServiceNow, надо разобрать три компонента архитектуры Now Platform.
Apache Jelly и двойная оценка шаблонов
ServiceNow использует Apache Jelly как template engine для рендеринга UI. По данным Traceable, ключевая штука - двойная оценка (double evaluation): переменные в тегахg: и j: обрабатываются раньше, чем теги g2: и j2:. Если атакующий контролирует значение, попадающее в первый раунд рендеринга, его результат может быть интерпретирован как исполняемый код на втором раунде. Классический Server-Side Template Injection, прямо по OWASP A03:2021 (Injection).GlideRecord: javascript:-evaluation в запросах к таблицам
GlideRecord - проприетарный API Now Platform для работы с таблицами. Тут нет текстового языка запросов в привычном смысле - всё через builder-интерфейс. Под капотом ServiceNow крутится MariaDB, но она никогда не экспонируется пользователю напрямую.По данным Searchlight Cyber, метод
addQuery при обработке значений фильтров поддерживает префикс javascript:, который вызывает оценку JavaScript-выражения:
JavaScript:
var gr = new GlideRecord('sys_user');
gr.addQuery('email', '>', "javascript:'wal' + 'ter'");
gr.query();
// ServiceNow выполняет JS-выражение 'wal' + 'ter',
// получает 'walter' и использует как аргумент запроса
la_due<javascript:gs.daysAgoStart(0)), но его наличие в addQuery с пользовательским вводом - это уже совсем другая история. Пользовательские данные попадают в addQuery из UI-страниц повсеместно, и далеко не все из этих страниц требуют аутентификации.Sandbox: два уровня изоляции скриптов
ServiceNow реализует двухуровневую изоляцию. Первый уровень - общий sandbox - ограничивает допустимые Java-классы и функции для всех JS-скриптов. Выполнение кода внутри него фактически эквивалентно правам администратора: доступ к конфигурационным файлам, чтение большинства таблиц, отправка команд на MID-серверы.Второй уровень - script sandbox - применяется к определённым источникам ввода, включая фильтры. Здесь объект
gs заменяется на GlideSystemSandbox с урезанным набором методов. Доступ к таблицам - только чтение под ограничительными ACL, а eval, new Function(...)() и определение функций через function запрещены. По данным Searchlight Cyber, запрет eval существует именно потому, что его вызов исполняет код вне constraints script sandbox - это был бы тривиальный побег из песочницы.CVE-2024-4879 и CVE-2024-5217: ServiceNow RCE уязвимость через template injection
Jelly Template Injection (CVE-2024-4879)
CVE-2024-4879 (CVSS 9.3 CRITICAL, CWE-1287 - Improper Validation of Specified Type of Input) - уязвимость валидации ввода в UI macros Now Platform. По NVD затрагивает релизы Vancouver и Washington DC; CISA KEV дополнительно упоминает Utah. CVE-2024-5217 по NVD затрагивает Washington DC, Vancouver и более ранние релизы (включая Utah). Вектор CVSS 4.0 содержит AT:N - специфические условия на стороне цели не требуются.По данным CISA KEV, это "jelly template injection vulnerability in UI macros", позволяющая неаутентифицированному пользователю удалённо исполнить код. Traceable описывает механику так: эксплуатация начинается с обхода HTML-санитизации - уязвимые версии позволяют переменной
jvar_page_title включать теги <style>, внутри которых payload не санитизируется и обрабатывается как XML. Дальше атакующий подменяет контекстный тег xmlns для переключения из пространства имён ServiceNow, что снимает ограничения на исполнение произвольного кода. Тонкость, которую описал Traceable: проверка контекста обходилась заменой двойных кавычек " на одинарные ' при указании пространств имён. Элегантно и обидно одновременно.Публичный PoC на Exploit-DB: EDB-52410 - "ServiceNow Multiple Versions - Input Validation & Template Injection" (автор: İbrahimsql, опубликован 2025-08-11).
Обход блеклиста (CVE-2024-5217)
CVE-2024-5217 (CVSS 9.2 CRITICAL, CVSS 4.0 вектор AT- CWE-184 (Incomplete List of Disallowed Inputs) - список запрещённых конструкций в GlideExpression script был неполным, атакующий находил конструкции, не попавшие в блеклист
- CWE-697 (Incorrect Comparison) - логика сравнения при проверке ввода работала некорректно, пропуская вредоносные конструкции, которые формально подпадали под запрет
CVE-2024-5178 (CVSS 6.9 MEDIUM, CWE-184, PR:H - нужен административный доступ) - отдельная post-auth уязвимость чтения чувствительных файлов на сервере. По NVD: "sensitive file read vulnerability" в релизах Washington DC, Vancouver и Utah. Не pre-auth - эксплуатируется только после получения привилегированного контекста (например, через CVE-2024-4879/5217). EPSS: 0.3359 (Top 5%).
Цепочка CVE-2024-4879 -> CVE-2024-5217 (pre-auth) с последующей эксплуатацией CVE-2024-5178 (post-auth, PR:H) покрывает сразу несколько категорий OWASP: A03:2021 (Injection - template injection как частный случай), A05:2021 (Security Misconfiguration - некорректная санитизация и неполный блеклист) и A08:2021 (Software and Data Integrity Failures - нарушение целостности обработки серверных шаблонов).
Это принципиально иной вектор, не связанный с Jelly template injection, - через
javascript:-evaluation в GlideRecord.Pre-auth sinks и скриптовая песочница
Согласно исследованию Searchlight Cyber, первый обнаруженный pre-auth sink, работающий во всех версиях, нашёлся в обработчикеassessment_thanks.do:
JavaScript:
// assessment_thanks.do - pre-auth endpoint
var metricGR = new GlideRecord("asmt_metric_type");
metricGR.addQuery('sys_id', jelly.sysparm_assessable_type);
metricGR.query();
// sysparm_assessable_type - GET-параметр от пользователя,
// попадает в addQuery без санитизации
sysparm_assessable_type передаётся напрямую в addQuery. Проверочный запрос: обращение к /assessment_thanks.do?sysparm_assessable_type=javascript:gs.addErrorMessage(1) (проверка: curl -sk 'https://target/assessment_thanks.do?sysparm_assessable_type=javascript:gs.addErrorMessage(1)' -o -). Если код исполняется, в теле ответа появится сообщение об ошибке (строка error-message или outputmsg_error в HTML). Но исследователи обнаружили, что код исполняется в контексте script sandbox - gs оказался экземпляром GlideSystemSandbox, а не GlideSystem.Побег из sandbox через script includes
Ключевая деталь: функцияgs.include() разрешена даже в script sandbox. Она загружает предустановленные библиотеки функций (script includes) в глобальную область видимости. Определение новых функций через function запрещено sandbox - но gs.include() загружает уже определённые функции из системных библиотек. По сути, песочница сама даёт инструмент для побега из себя.Searchlight Cyber сообщает, что этот механизм стал основой для полного побега из sandbox, что привело к unauthenticated RCE с компрометацией как самого инстанса ServiceNow, так и всех подключённых proxy-серверов. Детали escape-примитива описаны в их публикации.
Когда техника НЕ работает:
- Инстансы с патчем, закрывающим
javascript:-evaluation в фильтрах (конкретные версии патча не указаны в доступных публичных источниках на момент написания) - Инстансы с кастомной конфигурацией, где
assessment_thanks.doотключён или закрыт отдельным ACL - WAF-правила, блокирующие строку
javascript:в GET-параметрах - но не все WAF корректно обрабатывают URL-encoded варианты (%6a%61%76%61%73%63%72%69%70%74%3a)
Fingerprinting уязвимых инстансов при пентесте корпоративных платформ
[Применимо: внешний пентест, black box, recon-фаза]ServiceNow-инстансы hosted-развёртывания доступны по паттернам
<company>.service-now.com (hosted) или на кастомных доменах (self-hosted). Базовая разведка:- Проверить стандартные эндпоинты: обращение к
/login.do,/stats.do,/nav_to.doчерезcurl -sk https://target/login.do -o /dev/null -w "%{http_code}". Характерная HTML-разметка с упоминанием ServiceNow подтверждает платформу. - Определить релиз: в JS-файлах hosted-инстансов присутствуют маркеры версии (например, в
scripts/doctype.jsили в теле страницы/login.do) - Utah, Vancouver, Washington DC, Xanadu, Australia. Self-hosted инстансы могут скрывать эту информацию. - Проверить pre-auth эндпоинты: обращение к
/assessment_thanks.doбез cookie - если возвращается HTTP 200 вместо 302-редиректа на логин, эндпоинт доступен без аутентификации. - Проверить API-конфигурацию: по неподтверждённым данным, API-эндпоинты с
requires_authentication=falseмогут позволять запросы от Guest-аккаунта. Проверяется простым GET/POST без токена.
Enterprise pentest RCE: kill chain от initial access до lateral movement
Полная цепочка атаки на ServiceNow через pre-auth RCE в терминах MITRE ATT&CK:
- Exploit Public-Facing Application (T1190, Initial Access) - эксплуатация template injection или
javascript:-evaluation через HTTP-запрос к pre-auth эндпоинту - Выполнение кода в контексте Now Platform - атакующий исполняет скрипты в серверном окружении ServiceNow
- Data from Information Repositories (T1213, Collection) - запросы к таблицам через GlideRecord:
sys_user(пользователи),cmdb_ci(конфигурационные элементы),sys_properties(системные настройки),discovery_credentials(учётные данные для discovery) - Valid Accounts (T1078, Persistence / Initial Access) - использование извлечённых credentials для доступа к интегрированным системам (LDAP, SSO, сторонние API)
- Lateral movement через MID-серверы - ServiceNow MID (Management, Instrumentation, and Discovery) серверы стоят внутри корпоративной сети для интеграций. Компрометация платформы с отправкой команд на MID-сервер = выполнение кода внутри периметра
Ограничения техник и детект
Когда техники не работают
| Условие | CVE-2024-4879 / CVE-2024-5217 | javascript: evaluation (Searchlight Cyber research, CVE не присвоен) |
|---|---|---|
| Патченный инстанс (June 2024+) | Не работает | Зависит от отдельного патча |
| Hosted ServiceNow (service-now.com) | Автопатч применён | Автопатч применён |
| Self-hosted без патча | Работает | Работает |
| WAF с SSTI-сигнатурами | Частичная блокировка | Частичная блокировка |
| Кастомные ACL на pre-auth эндпоинтах | Может ограничить sink | Может ограничить sink |
CVE-2024-5178 (чтение файлов, PR:H) - не pre-auth сама по себе; в цепочке используется после получения привилегированного контекста через CVE-2024-4879/5217.
Рекомендации по детекту
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Pre-auth RCE в ServiceNow - через Jelly template injection (CVE-2024-4879/CVE-2024-5217, 2024) и родственный вектор через
javascript:-evaluation в GlideRecord, описанный Searchlight Cyber (CVE не присвоен) - показывают не серию изолированных багов, а системную проблему архитектуры. Корень один: пользовательский ввод попадает в контексты, где платформа исполняет код, а механизмы изоляции (sandbox, блеклисты, ACL) обходятся. ServiceNow пытается решить это расширением блеклистов и ужесточением sandbox - но каждый исследовательский цикл находит новые sinks и новые способы побега. CWE-697 (Incorrect Comparison) в той же уязвимости добавляет: даже внесённые в блеклист конструкции обходились из-за ошибок в логике сравнения. Это не баг - это архитектурное решение, которое генерирует баги.Для пентестера вывод прагматичный. ServiceNow - высокоприоритетная цель на внешнем периметре. Self-hosted инстансы патчатся медленно; hosted - автоматически, но конфигурационные ошибки вроде
requires_authentication=false на Scripted REST живут месяцами. EPSS 0.9998 для CVE-2024-4879 означает: если вы нашли непатченный инстанс - с высокой вероятностью его уже нашёл кто-то другой. На аудите enterprise-платформ я привык начинать с проверки именно таких точек: pre-auth endpoint, fingerprint версии, проверка наличия патча. Три шага - и либо идёшь дальше по скоупу, либо уже есть initial access. А дальше GlideRecord покажет всё, что лежит в таблицах - и часто это оказывается куда ценнее, чем сам shell.
Последнее редактирование модератором: