Корпоративный конверт с восковой печатью, рассечённой скальпелем, на чёрном антистатическом коврике. Внутри — распечатка с фрагментом кода, резкий верхний свет, криминалистическая цветовая палитра.


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
Unauthenticated RCE на такой платформе - это не компрометация одного сервиса. Это точка, из которой атакующий получает полную карту инфраструктуры жертвы и учётные данные для lateral movement - без единого шага разведки внутри периметра. При наличии API-эндпоинтов с отключённой аутентификацией потенциально доступны тикеты, данные сотрудников, asset inventories и конфигурации корпоративных систем.

Архитектура ServiceNow и pre-auth attack surface​

1784784118155.webp

[Применимо: внешний пентест, 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​

1784784146269.webp

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:P - эксплуатация требует специфических условий на стороне цели, в отличие от CVE-2024-4879 с AT:N) усиливает цепочку и связана с двумя CWE:
  • CWE-184 (Incomplete List of Disallowed Inputs) - список запрещённых конструкций в GlideExpression script был неполным, атакующий находил конструкции, не попавшие в блеклист
  • CWE-697 (Incorrect Comparison) - логика сравнения при проверке ввода работала некорректно, пропуская вредоносные конструкции, которые формально подпадали под запрет
CISA KEV описывает уязвимость как "incomplete list of disallowed inputs vulnerability in the GlideExpression script", подтверждая активную эксплуатацию с 29 июля 2024 года с дедлайном патчинга 19 августа 2024. EPSS: 0.9963 (Top 0.1%).

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). Базовая разведка:
  1. Проверить стандартные эндпоинты: обращение к /login.do, /stats.do, /nav_to.do через curl -sk https://target/login.do -o /dev/null -w "%{http_code}". Характерная HTML-разметка с упоминанием ServiceNow подтверждает платформу.
  2. Определить релиз: в JS-файлах hosted-инстансов присутствуют маркеры версии (например, в scripts/doctype.js или в теле страницы /login.do) - Utah, Vancouver, Washington DC, Xanadu, Australia. Self-hosted инстансы могут скрывать эту информацию.
  3. Проверить pre-auth эндпоинты: обращение к /assessment_thanks.do без cookie - если возвращается HTTP 200 вместо 302-редиректа на логин, эндпоинт доступен без аутентификации.
  4. Проверить API-конфигурацию: по неподтверждённым данным, API-эндпоинты с requires_authentication=false могут позволять запросы от Guest-аккаунта. Проверяется простым GET/POST без токена.
Тут критически важно разграничивать hosted и self-hosted инстансы. Self-hosted патчатся вручную и часто отстают на несколько релизов. Hosted - автопатч, но конфигурационные ошибки никуда не деваются.

Enterprise pentest RCE: kill chain от initial access до lateral movement​

1784784176429.webp

Полная цепочка атаки на ServiceNow через pre-auth RCE в терминах MITRE ATT&CK:
  1. Exploit Public-Facing Application (T1190, Initial Access) - эксплуатация template injection или javascript:-evaluation через HTTP-запрос к pre-auth эндпоинту
  2. Выполнение кода в контексте Now Platform - атакующий исполняет скрипты в серверном окружении ServiceNow
  3. Data from Information Repositories (T1213, Collection) - запросы к таблицам через GlideRecord: sys_user (пользователи), cmdb_ci (конфигурационные элементы), sys_properties (системные настройки), discovery_credentials (учётные данные для discovery)
  4. Valid Accounts (T1078, Persistence / Initial Access) - использование извлечённых credentials для доступа к интегрированным системам (LDAP, SSO, сторонние API)
  5. Lateral movement через MID-серверы - ServiceNow MID (Management, Instrumentation, and Discovery) серверы стоят внутри корпоративной сети для интеграций. Компрометация платформы с отправкой команд на MID-сервер = выполнение кода внутри периметра
Аналогичный сценарий - несанкционированные запросы к таблицам ServiceNow от Guest-аккаунта через API-эндпоинт с отключённой аутентификацией - типовой вектор для этого класса уязвимостей.

Ограничения техник и детект​

Когда техники не работают​

УсловиеCVE-2024-4879 / CVE-2024-5217javascript: 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.
 
Последнее редактирование модератором:
Мы в соцсетях:

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

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

HackerLab