На одном из последних red team-проектов мы перехватили SAMLResponse в Burp, переместили подписанный Assertion в другую ветку DOM-дерева, вставили поддельный с
NameID=admin@company.local на его место - и SP пустил нас как доменного администратора.Подпись осталась валидной: валидатор проверил оригинальный элемент, а приложение обработало подложный. Три правки в XML, ноль взаимодействия с IdP. Это XML Signature Wrapping, и он работает - от самописных SP до GitLab EE. Дальше разберу три вектора атак на SAML аутентификацию: XSW, Golden SAML и эксплуатацию свежих CVE в популярных библиотеках. Каждый - с позицией в kill chain, предусловиями и конкретными инструментами.SAMLResponse - это XML-сообщение с цифровой подписью, отправляемое поставщиком идентификационных данных (IdP) поставщику услуг (SP) во время входа в систему с использованием единого входа (SSO).
Подписанный Assertion - это защищенный криптографической подписью документ или пакет данных, удостоверяющий личность пользователя, его права доступа или подтверждающий определенные факты.
SP - приложение
SAML-флоу глазами атакующего
Для пентестера SAML - цепочка доверия между тремя участниками: браузером пользователя (User Agent), Service Provider (SP) и Identity Provider (IdP). SP-initiated flow - самый распространённый вариант: Подробнее - в нашем материале про атаки на аутентификацию.- Пользователь заходит на SP, SP генерирует AuthnRequest и отправляет редирект на IdP
- IdP аутентифицирует пользователя (логин, пароль, MFA)
- IdP формирует SAMLResponse - XML-документ с Assertion, подписанным закрытым ключом IdP - и через браузер отправляет его обратно на SP
- SP валидирует подпись, извлекает атрибуты из Assertion (NameID, роли, группы) и предоставляет доступ
XML Signature Wrapping - подмена Assertion при валидной подписи
Механика XSW-атаки
XML Signature Wrapping (XSW) - класс атак, эксплуатирующий разницу между двумя фазами обработки SAML: валидацией подписи и извлечением данных. По данным IBM, атакующий вставляет поддельные элементы в XML-документ, не ломая валидность цифровой подписи. Валидатор проверяет одну часть документа, приложение обрабатывает другую.Технически это работает так: подписанный Assertion ссылается на элемент по ID через атрибут
URI="#_id1234" в блоке Reference. Атакующий перемещает подписанный Assertion в другую часть DOM-дерева, а на его место ставит поддельный с произвольным NameID. Если SP ищет Assertion по XPath (например, //saml:Assertion) и берёт первый найденный - он обработает поддельный, хотя валидатор подписи корректно проверил оригинальный.Предусловия. Работает если:
- Есть хотя бы один легитимный SAMLResponse от IdP (перехват через Burp или собственная учётка на SP).
- SP использует уязвимую реализацию проверки подписей.
- SP привязывает Assertion к конкретной сессии и строго проверяет
InResponseTo. - SP верифицирует, что обрабатываемый элемент - тот самый, на который указывает Reference URI.
Применимость: внешний пентест (SP доступен через интернет, использует SAML SSO), внутренний пентест (доступ к корпоративному SSO-порталу). Категория MITRE ATT&CK: T1212 (Exploitation for Credential Access) при initial access или T1550.001 (Application Access Token) при lateral movement к другим SP.
Варианты XSW и практика с SAML Raider
По данным HackTricks и исследования Juraj Somorovsky "On Breaking SAML", задокументировано восемь основных вариантов XSW. На практике три работают чаще остальных:| Вариант | Стратегия | Когда применять |
|---|---|---|
| XSW #1 | Новый корневой элемент оборачивает подпись, поддельный Response на верхнем уровне | SP использует //Assertion без привязки к конкретному родителю |
| XSW #3 | Поддельный Assertion на том же уровне, что оригинальный | SP берёт первый Assertion в документе |
| XSW #7 | Поддельный Assertion внутри элемента Extensions | Обход schema validation в OpenSAML и аналогах с нестрогой проверкой |
| XSW #4-#6 | Варианты с вложением оригинального Assertion в поддельный | Агрессивное изменение структуры, работает против парсеров с permissive XPath |
| XSW #8 | Оригинальный Assertion вложен в менее строгий XML-элемент | Обход schema validation в библиотеках, не проверяющих типы вложенных элементов |
На пентесте я обычно начинаю с XSW #1 и #3 - они срабатывают на наибольшем количестве реализаций. Если не прокатывает, перехожу к #7 (Extensions), потом к #4-#6.
Требования к окружению для работы с SAML Raider:
- ОС: любая (Burp Suite кроссплатформенный)
- Burp Suite Professional или Community Edition (проверено на 2024.x и 2025.x)
- SAML Raider - установка через BApp Store в Burp
- Браузер, настроенный на проксирование через Burp
- Перехваченный SAMLResponse от целевого IdP (собственная учётка или перехват)
Ограничения. SAML Raider покрывает стандартные XSW #1-#8. Продвинутые техники - namespace confusion, Void Canonicalization (описаны в исследовании PortSwigger от декабря 2025) - требуют ручной модификации XML. Исследователи показали, что вместо поиска подписанного SAML Assertion можно переиспользовать любой XML-документ, подписанный закрытым ключом IdP, - а это уже совсем другая поверхность атаки.
Parser differentials: почему библиотеки ломаются снова и снова
Исследования PortSwigger вскрыли фундаментальную причину живучести XSW-уязвимостей: многие SAML-библиотеки используют два разных XML-парсера - один для валидации подписи, другой для извлечения данных. В Ruby-SAML, например, один парсер (REXML) извлекает DigestValue и SignatureValue, а другой (Nokogiri, обёртка над libxml2) выполняет каноникализацию и хеширование. Различия в обработке namespaces, комментариев и DTD между парсерами создают эксплуатируемые расхождения.В Ruby-SAML оба парсера искали Signature по XPath
//ds:Signature, возвращая первое вхождение. Дополнительная логика на REXML проверяла, что родительский элемент Signature - это Assertion. Но если атакующий помещал поддельный Assertion с вложенной Signature так, что оба парсера "видели" разные элементы - валидация проходила, а приложение обрабатывало поддельные данные. Два парсера в одном приложении - это как два замка на одной двери, каждый из которых открывается своим ключом.Golden SAML - подделка токенов через ключ подписи IdP
Цепочка эксплуатации
Если XSW обманывает SP через структуру XML, то Golden SAML - это полная компрометация доверия. Атакующий, завладевший закрытым ключом Token Signing Certificate из IdP, генерирует криптографически валидные SAML Assertion для любого пользователя, к любому SP, с любыми атрибутами. В терминологии MITRE ATT&CK - T1606.002 (Forge Web Credentials: SAML Tokens).Microsoft характеризует Golden SAML как редкую, но высокоэффективную технику постэксплуатации. Редкость компенсируется масштабом: один украденный ключ компрометирует все учётные записи организации. Организации подключают десятки приложений к одному SSO, и один форжированный токен потенциально открывает доступ ко всем.
Предусловия. Работает если:
- Получены привилегии Domain Admin или локального администратора на ADFS-хосте.
- Извлечён Token Signing Certificate (закрытый ключ).
- Известны идентификаторы целевых SP (Issuer URI, Audience).
- Без предварительной компрометации on-prem инфраструктуры. Golden SAML - не initial access, это lateral movement после глубокого проникновения.
Kill chain:
- Компрометация ADFS-сервера - privilege escalation до Domain Admin или локального администратора на ADFS-хосте (T1556.007, Modify Authentication Process: Hybrid Identity)
- Извлечение закрытого ключа из Windows Internal Database (WID) или SQL Server, где ADFS хранит конфигурацию (T1552.004, Unsecured Credentials: Private Keys). Инструмент:
ADFSDumpдля экспорта конфигурации и ключей - Генерация поддельного Assertion с произвольными атрибутами - NameID, роли, группы. Инструмент:
shimit(Python) для создания SAML Response с указанным ключом и параметрами целевого SP - Доставка токена - подставить сгенерированный SAMLResponse в POST-запрос на ACS-эндпоинт SP через браузер
Silver SAML - облегчённый вариант для Entra ID
Semperis раскрыла технику Silver SAML, работающую с Microsoft Entra ID (ранее Azure AD) без компрометации ADFS. Если организация использует externally imported signing certificate в Entra ID (а не самоподписанный сертификат Entra), атакующий с доступом к этому сертификату может генерировать поддельные SAML Response. Semperis выложила PoC-инструментSilverSAMLForger. Microsoft квалифицировала проблему как не соответствующую критериям немедленного решения, но рекомендовала использовать только самоподписанные сертификаты Entra ID. Типичная позиция - «это не баг, это фича» (но сертификат лучше поменяйте).CVE в SAML-библиотеках: что эксплуатируется прямо сейчас
Многие обходы SAML аутентификации бьют не в архитектуру протокола, а в баги конкретных библиотек. Три свежих CVE - все с CWE-347 (Improper Verification of Cryptographic Signature) - показывают масштаб проблемы.CVE-2024-45409: Ruby-SAML - CVSS 10.0 (Critical)
Уязвимые версии:
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Применимость: external pentest, если целевой SP работает на Rails-стеке с ruby-saml (GitLab CE/EE, приложения на OmniAuth). Fingerprinting: Rails-сессия в cookies, характерные HTTP-заголовки. Исправлено: версии 1.17.0 и 1.12.3.
CVE-2025-47949: samlify - CVSS 9.9 (Critical)
Уязвимая версия: samlify < 2.10.0 (Node.js). Классический Signature Wrapping: атакующий, имея любой подписанный IdP XML-документ, подделывает SAML Response и аутентифицируется как произвольный пользователь. Вектор:CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N - максимальная доступность. По данным Obsidian Security, приложения на уязвимых версиях принимали неподписанные или некорректно подписанные Assertion как валидные. Исправлено: версия 2.10.0. Fingerprinting: Express-сессия в cookies, Node.js-стек.CVE-2025-23369: GitHub Enterprise Server - CVSS 7.6 (High)
Уязвимые версии: GHES < 3.12.14, < 3.13.10, < 3.14.7, < 3.15.2, < 3.16.0. Improper verification of cryptographic signature, позволяющая spoofing подписи для внутренних пользователей. Эксплуатация требует: GHES использует SAML SSO, атакующий уже является существующим пользователем (PR:L). Вектор:CVSS:4.0 с AC:H и ATP - высокая сложность, дополнительные предусловия. Severity - High (7.6), не Critical. Это privilege escalation для аутентифицированного пользователя, не полный bypass. Обнаружена через GitHub Bug Bounty. По данным PortSwigger, уязвимость связана с особенностями обработки namespaces в libxml2 - опять parser differential между компонентами валидации.Историческая серия: XML Comment Injection (2017-2018)
Ранний массовый вектор - вставка XML-комментариев в NameID для обрезки строки:
XML:
<NameID>admin@target.com<!--
-->.evil.com</NameID>
admin@target.com вместо полной строки admin@target.com.evil.com. Затронуты: OneLogin PythonSAML (CVE-2017-11427), Ruby-SAML (CVE-2017-11428), Clever saml2-js (CVE-2017-11429), OmniAuth-SAML (CVE-2017-11430) - все CWE-287 (Improper Authentication); Shibboleth (CVE-2018-0489, CWE-347); Duo Network Gateway (CVE-2018-7340, CVSS 7.5 High, CWE-287/CWE-347). Актуальные версии библиотек пропатчены, но на legacy-инфраструктуре вектор по-прежнему живой.Выбор вектора: decision tree для атак на SAML аутентификацию
| Условие | Вектор | Инструмент | Kill chain этап |
|---|---|---|---|
| Есть SAMLResponse, SP на уязвимой библиотеке | XSW #1-#8 | SAML Raider (Burp) | Initial Access |
| SP на ruby-saml <= 1.16.0 | CVE-2024-45409 | Synacktiv PoC | Initial Access |
| SP на samlify < 2.10.0 | CVE-2025-47949 | Ручная модификация XML | Initial Access |
| Скомпрометирован ADFS, нужен доступ к облачным SP | Golden SAML | ADFSDump + shimit | Lateral Movement |
| Доступ к external signing cert в Entra ID | Silver SAML | SilverSAMLForger | Lateral Movement |
| Legacy SP, библиотеки 2017-2018 без обновлений | Comment Injection | Ручная правка XML | Initial Access |
Fingerprinting SP перед атакой - обязательный первый шаг. Определить стек по HTTP-заголовкам, cookies (Rails-сессия -> ruby-saml, Express-сессия -> samlify), страницам ошибок, метатегам. Без знания библиотеки и версии выбор XSW-варианта превращается в слепой перебор. По формулам всё красиво, а на практике decay ощущается только когда сам прогоняешь сабмишены на реальном SSO-стенде. Если хочется потренироваться в контролируемой среде - на HackerLab.pro (https://hackerlab.pro) есть задачи в категории web, построенные на схожих примитивах с манипуляцией аутентификационных токенов.
Что видит защита и где слепые зоны SIEM при SAML-атаках
XSW и эксплуатация CVE
SP-side: если SP логирует raw SAML Assertion (многие SP в дефолтной конфигурации этого не делают - пишут только NameID и результат), аномалии в XML-структуре теоретически детектируемы. На практике при успешном XSW лог выглядит как легитимный вход целевого пользователя.IdP-side: XSW не затрагивает IdP. В журналах IdP будет легитимная аутентификация пользователя-атакующего (от чьего имени получен оригинальный SAMLResponse). Аномалию можно поймать корреляцией: один пользователь аутентифицируется в IdP, а в SP фиксируется вход другого. Но для этого нужна интеграция логов обеих систем - а это на практике встречается редко.
Golden SAML
По данным Microsoft, Golden SAML создаёт ноль событий аутентификации в IdP. IdP в атаке не участвует вообще. Мониторинг failed logins, impossible travel, MFA failures - бесполезен. Стандартные SIEM-корреляции пропускают атаку полностью.Детекция возможна через: поведенческий анализ post-authentication (нетипичные SP, время, объёмы); мониторинг изменений ADFS-конфигурации - Event ID 307 (ротация Token Signing Certificate) в ADFS Audit Log; мониторинг изменений
PreferredTokenSigningKeyThumbprint в журналах Entra ID ApplicationManagement; Microsoft Defender for Identity (содержит алерты для Golden SAML).Главная слепая зона: если ADFS Audit Log не интегрирован в SIEM (а это нередкая ситуация - организации не трогают настройки ADFS годами), компрометация ключа подписи останется невидимой, пока behavioral analytics не зацепит аномальные паттерны доступа. А может и не зацепит.
Чеклист для blue team
- Интегрировать ADFS Audit Log в SIEM
- Настроить алерт на Event ID 307 (изменение signing certificate) в ADFS
- Мониторить
PreferredTokenSigningKeyThumbprintв Entra ID Audit - Использовать только самоподписанные сертификаты Entra ID (митигация Silver SAML)
- Корреляция SP и IdP: NameID в SP должен соответствовать аутентифицированному пользователю в IdP
- Обновить SAML-библиотеки: ruby-saml >= 1.17.0, samlify >= 2.10.0, GHES до актуальных версий
- Проверить, что SP привязывает Reference URI к конкретному обрабатываемому элементу - не к первому найденному Assertion по XPath
Проблема глубже отдельных CVE. SAML 2.0 - стандарт 2005 года, построенный на XML. Спецификация XML-подписи допускает десятки способов размещения подписи относительно подписанных данных: enveloped, enveloping, detached. Каждая библиотека интерпретирует допустимые размещения по-своему, каждая интерпретация - потенциальный XSW-вектор. Исследователи продолжают находить новые классы атак на каноникализацию XML, и конца этому не видно.
Golden SAML - другая история. Тут проблема не в коде, а в архитектуре: организации годами тянут ADFS как мост между on-prem AD и облаком, и этот мост становится single point of compromise. Microsoft прямо рекомендует переход на чисто облачную идентификацию, но для многих это проект на годы.
Мой прогноз: в ближайший год мы увидим ещё несколько критических CVE в SAML-библиотеках - исследование parser differentials набирает обороты. Для пентестера это означает одно: fingerprinting SAML-стека SP - не опциональный шаг, а первый. Знать, какая библиотека, какой версии, какие парсеры под капотом - разница между «получил DA за час» и «потратил день на слепой перебор XSW-вариантов».
Последнее редактирование модератором: