
Эксплойт для CVE-2021-21239: обход проверки подписи SAML в pysaml2/Redash. Формирует поддельные SAML-ответы со встроенными открытыми ключами для выдачи себя за пользователей и повышения привилегий через JIT-провижининг.
Security Assertion Markup Language (SAML) — это открытый стандарт для обмена данными аутентификации и авторизации между сторонами в федеративной системе идентификации. Он обеспечивает единый вход (SSO) между доменами. Ключевые компоненты:
В типичном потоке SAML SP перенаправляет пользователя в IdP для аутентификации. IdP возвращает подписанный ответ SAML, содержащий утверждения о пользователе (например, email, имя). SP проверяет подпись и подготавливает или выполняет вход пользователя.
CVE-2021-21239 — это уязвимость обхода проверки подписи в библиотеке pysaml2 (версии <6.5.0), используемой Redash <=10.1.0 для SAML SSO. На высоком уровне она позволяет злоумышленнику подделать ответ SAML с произвольным встроенным открытым ключом, что дает возможность выдать себя за пользователя и повысить привилегии через JIT-подготовку.
Уязвимость возникает из-за того, как pysaml2 вызывает xmlsec1 для проверки подписей SAML. Xmlsec1 по умолчанию предпочитает встроенные открытые ключи в ответа SAML настроенному сертификату IdP. Злоумышленник может создать ответ SAML с самостоятельно сгенерированной парой ключей RSA, встроить открытый ключ в и подписать утверждение закрытым ключом. Поскольку pysaml2 не ограничивает использованием только доверенного сертификата IdP, поддельная подпись считается действительной, что позволяет злоумышленнику войти как любой пользователь (например, администратор) и получить максимальные привилегии.
<ds:KeyInfo><ds:RSAKeyValue>xmlsec1На уровне кода уязвимость существует в sigver.py pysaml2 (функция check_signature). В списке команд xmlsec1 отсутствует опция --enabled-key-data raw-x509-cert, что позволяет xmlsec1 использовать ненадежные встроенные ключи:
com_list = [
self.xmlsec, '--verify', '--enabled-reference-uris', 'empty,same-doc',
'--pubkey-cert-pem', cert_file_name,
'--id-attr:%s' % id_attr, node_name,
'--node-id', nodeid, '--output', output_file_name, xml_file_name
]
Это позволяет атаки, при которых злоумышленник изменяет email в <saml:NameID> для выдачи себя за любого пользователя, используя JIT-подготовку.
Для тестирования эксплойта используется локальный экземпляр Redash (v10.1.0 или более ранняя версия), запущенный с помощью Docker Compose. Настройка включает конфигурацию SAML SSO с IdP Google:
Эта настройка позволяет протестировать поддельный ответ SAML, отправленный через Python-скрипт или Burp Suite, подтверждающий повышение привилегий.
Уязвимость возникает из-за того, что вызов xmlsec1 в pysaml2 позволяет использовать встроенные ключи для проверки, обходя доверенный сертификат IdP. Злоумышленник генерирует пару ключей RSA, создает ответ SAML с открытым ключом в <ds:RSAKeyValue>, изменяет атрибуты (например, email на администратора) и подписывает утверждение. Xmlsec1 проверяет с использованием встроенного ключа, считая его действительным.
Исправление было реализовано в pysaml2 v6.5.0 (первичный коммит от 17 января 2021 г.) в src/saml2/sigver.py. Список команд xmlsec1 был обновлен, чтобы включить --enabled-key-data raw-x509-cert, ограничивая проверку настроенным сертификатом IdP:
com_list = [
self.xmlsec, '--verify', '--enabled-reference-uris', 'empty,same-doc',
'--pubkey-cert-pem', cert_file_name,
'--enabled-key-data', 'raw-x509-cert',
'--id-attr:%s' % id_attr, node_name,
'--node-id', nodeid, '--output', output_file_name, xml_file_name
]
Это обеспечивает проверку цепочки доверия, предотвращая использование встроенных ключей. Redash исправил это обновлением pysaml2 в более поздних версиях (например, v11+). Уязвимые версии не использовали --insecure; ошибка заключалась в отсутствии опции ограничения.
Код эксплойта реализован в файле cve-2021-21239.py. Этот скрипт Python автоматизирует процесс подделки ответа SAML для эксплуатации CVE-2021-21239 в Redash <=10.1.0, позволяя выдать себя за пользователя и повысить привилегии через JIT-подготовку. Эксплойт нацелен на SAML IdP Google Workspace, но атака была протестирована и с другими IdP (keycloak). Скрипт выполняет следующие шаги:
email="[email protected]").idpid из конечной точки входа SAML Redash, если он не указан, обеспечивая совместимость с конфигурацией цели.SAMLResponseTempalte.xml) с заполнителями для email, имен, временных меток и ID утверждения. Динамические временные метки UTC генерируются с окном действия в 5 минут, чтобы пройти проверку Redash.xmlsec для подписи элемента <saml:Assertion> с помощью RSA-SHA256, встраивая открытый ключ в <ds:RSAKeyValue> для эксплуатации уязвимости./saml/callback?org_slug=default).Эксплуатация CVE-2021-21239 требовала создания поддельного ответа SAML, который Redash принимает через JIT-подготовку. Ключевые трудности и обходы:
<ds:RSAKeyValue>, подписью закрытым ключом.xmlsec1 сработали, но библиотека Python xmlsec вызывала несовпадение дайджеста из-за проблем с пробелами/канонизацией. Обход путем сериализации XML в одну строку (etree.tostring(..., pretty_print=False)) перед подписью.NotOnOrAfter вызывало отклонение; обход с использованием динамических временных меток UTC с окном в 5 минут.SAMLResponse, вызывая ошибки разбора; обход путем отправки необработанных данных формы.Эти трудности подчеркивают необходимость точной манипуляции XML и настройки окружения для эффективной эксплуатации уязвимости. Предоставленный код эксплойта успешно демонстрирует это, подделывая ответ SAML для выдачи себя за пользователей и получения доступа.