Небезопасная аутентификация. Ищем баги в приложениях с Single Sign-On на базе SAML — Хакер

Configure the service provider

This tutorial will use Zendesk as the service provider, but you can follow along with any SP of your choosing.

To configure your chosen service provider, run through the following steps in your Auth0 dashboard:

  1. Click on SSO Integrations in the sidebar
  2. Click on the red button in the top right corner, Create SSO Integration
  3. Select the service provider you’d like to configure
  4. Enter the name and/or any identifying information required and press Save

Zendesk Auth0 service provider setupTutorial for your specific service provider

Note: This step will require you to input some values on the service provider’s side.

Here’s what that looks like for Zendesk.

How does saml authentication work?

Now that you’ve seen the high-level overview of how SAML authentication works, let’s look at some of the technical details to see how everything is accomplished.

SAML single sign-on authentication typically involves a service provider and an identity provider. The process flow usually involves the trust establishment and authentication flow stages.

Consider this example:

  • Our identity provider is Auth0
  • Our service provider is a fictional service, Zagadat

Note: The identity provider could be any identity management platform.

How does sso work?

Authentication with SSO relies on a trust relationship between domains (websites). With single sign-on, this is what happens when you try to log in to an app or website:

More auth0 saml configurations

Auth0 is adaptable when it comes to SAML configuration. Here are some of the other ways you can configure Auth0:

Prerequisites

The following image shows a list of the service providers Auth0 supports out-of-the-box, but you also have the option of configuring a custom service provider in the dashboard.

Saml authentication with auth0

When it comes to implementing SAML, Auth0 is extremely extensible and able to handle several scenarios:

For this example, you’ll learn how to implement SAML authentication using Auth0 as the identity provider.

Saml sso flow

The diagram below illustrates the single sign-on flow for service provider-initiated SSO, i.e. when an application triggers SSO.

Sso strategy

SAML is an XML-based open-standard data format for exchanging authentication and authorization data between parties, in particular, between an identity provider and a service provider.

OAuth is an open protocol to allow secure authorization in a simple and standard method from web, mobile, and desktop applications.

What is saml

Before jumping into the technical jargon, let’s look at an example that demonstrates what SAML is and why it’s beneficial.

You just started working at a new company, Wizova. They’ve given you a work email address and access to a dashboard. Once you sign in to this dashboard, you’re presented with the icons of all of the external services the company uses: Salesforce, Expensify, Jira, AWS, and more.

You click on the Salesforce icon, some magic happens in the background, and before you know it, you’re signed into Salesforce without ever entering any credentials!

As you might have guessed, the “magic” was actually SAML in action. So what’s going on here?

SAML stands for Security Assertion Markup Language. It is an XML-based open-standard for transferring identity data between two parties: an identity provider (IdP) and a service provider (SP).

Xpath-инъекции

Еще одна интересная уязвимость — это XPath-инъекция. Рассмотрим, как происходит проверка подписи SAML Response. Обычно код, осуществляющий проверку подписи, ищет элемент <ds:Signature> и из дочернего элемента <ds:Reference> извлекает атрибут URI.

Если приложение не производит проверку значения URI на наличие XPath-конструкций при составлении выражения, то такая реализация уязвима к XPath-инъекциям.

Свежая XPath-инъекция найдена в конце 2022 года в ruby-saml. Ниже представлена строка из xml_security.rb, которая стала причиной инъекции:

hashed_element = document.at_xpath("//*[@ID='#{uri[1..-1]}']")

В случае с Ruby эта уязвимость приводит к RCE. Во всем виновата особенность реализации XPath в Ruby, которая выполняет shell команды внутри обратных кавычек. Если приложение использует ruby-saml, то для определения наличия уязвимости необходимо в атрибут URI элемента подставить следующее значение:

Xxe повсюду

SAML-сообщения представляют собой XML. Это означает, что тестируемое приложение потенциально подвержено уязвимостям, связанным с парсингом XML. Сюда можно отнести уязвимости XML External Entities (XXE), Server-Side Request Forgery (SSRF) и XML Entity Expansion (XEE, в массах более известна как Billion Laughs attack).

Эти уязвимости очень распространены, когда речь идет о парсинге XML. На страницах Хакера про эти уязвимости не раз писали, поэтому я не буду подробно на них останавливаться. Только порекомендую хорошую «методичку» по данным уязвимостям. Эти уязвимости работают, несмотря на то что SAML-сообщение подписано, так как проверка подписи происходит уже после парсинга XML.

Первым делом при тестировании безопасности SAML SSO нужно перехватить сообщение Response и заменить его на следующее:

Арсенал для тестирования saml sso

На данном этапе у тебя есть тестируемое приложение с работоспособным SAML SSO. Разберемся, какие инструменты использовать для тестирования безопасности.

Конечно, в первую очередь утилиты с сайта, которые ранее упоминались:

  • раздел CODE/DECODE позволит тебе закодировать или декодировать сообщения SAML;
  • раздел SIGN позволит тебе подписать SAML-сообщения, используя секретный ключ;
  • раздел VALIDATE позволит тебе проверить подпись у SAML-сообщения;
  • раздел ENCRYPT/DECRYPT позволит тебе зашифровать или расшифровать SAML-сообщения, для расшифровки понадобится секретный ключ;
  • раздел EXAMPLES содержит примеры различных SAML-сообщений.

Если ты занимаешься веб-безопасностью, то, скорее всего, в твоем хакерском арсенале есть Burp Suite. Я представлю два плагина, которые предназначены для тестирования SAML. Ты можешь использовать эти плагины даже с бесплатной версией Burp Suite.

Первый плагин — это SAML Editor, написан на Python. Для того чтобы он заработал, придется установить Jython standalone и указать в настройках Burp Extender путь к Jython. Плагин очень простой, он добавляет дополнительную табу с именем SAML, которая позволяет редактировать SAML-сообщения на лету (рис. 12). Больше он ничего не умеет, его удобно использовать, чтобы быстро отредактировать сообщение.

Рис. 12. Плагин SAML Editor
Рис. 12. Плагин SAML Editor

Атаки xsw

XSW — это атака на процедуру проверки подписи, она заключается в том, что приложение проверяет подпись одних данных, а при обработке использует другие. В контексте SAML данная атака позволяет атакующему, имеющему учетную запись в приложении, аутентифицироваться как любой другой пользователь.

Предположим, что IdP подписывает только assertion и не подписывает само сообщение. Наше приложение принимает Response, проверяет подпись assertion и аутентифицирует пользователя. SAML Response показан на рис. 15. При проверке подписи приложение ищет при помощи XPath элемент , у которого атрибут ID равен значению abc.

Рис. 15. Оригинальный SAML Response
Рис. 15. Оригинальный SAML Response

Теперь попробуем модифицировать оригинальный SAML Response. Добавим в сообщение элемент <samlp:Extensions>, который содержит из оригинального сообщения. По спецификации SAML элемент <samlp:Extensions> является необязательным и может содержать внутри себя любые элементы.

Также в сообщение вместо оригинального элемента <saml:Assertion ID = “abc”> мы вставляем свой элемент <saml:Assertion ID = “evil”>. В качестве подписи для <saml:Assertion ID = “evil”> мы используем подпись для <saml:Assertion ID = “abc”>. После манипуляций SAML Response выглядит, как показано на рис. 16.

При проверке подписи приложение использует элемент <saml:Assertion ID = “abc”>, который является дочерним для . Проверка подписи успешно проходит. Но для аутентификации пользователя приложение использует элемент <saml:Assertion ID = “evil”>. Это и есть XSW-атака.

Рис. 16. Модифицированный SAML Response
Рис. 16. Модифицированный SAML Response

Атаки на зашифрованные assertions

SAML позволяет шифровать assertions, если assertion содержит конфиденциальную информацию. SAML не позволяет шифровать отдельные атрибуты, поэтому assertion шифруется целиком. Пример SAML Response с зашифрованным assertion доступен здесь.

В сообщение Response вместо элемента <saml:Assertion> присутствует элемент <saml:EncryptedAssertion>, зашифрованный и закодированный в Base64 assertion, а также симметричный ключ шифрования, оба находятся внутри элементов <xenc:CipherData>.

Для шифрования симметричного ключа шифрования используется алгоритм RSAES-PKCS1-v1_5. Для шифрования данных обычно используется блочный шифр (AES) в режиме CBC.

Если при расшифровывании assertion приложение выступает в качестве Оракула (Oracle), то после расшифровки оно сообщает о том, что padding неверный или расшифрованное сообщение не является валидным XML. Приложение может сообщать это в виде явного сообщения об ошибке либо в виде различного тайминга.

Есть еще одно условие для проведения атаки на XML-шифрование: атакующий должен иметь возможность изменять зашифрованные данные. Подпись сообщения проверяется раньше, чем расшифровываются данных. Поэтому приложение должно быть уязвимо к ошибкам проверки подписи, которые были рассмотрены ранее.

Юрай Соморовски (Juraj Somorovsky) опубликовал работу, посвященную атакам на XML-шифрование. В работе описан алгоритм, который позволит атакующему расшифровать при выполнении двух условий: приложение уязвимо к ошибкам проверки подписи и приложение выступает в качестве Оракула.

Также в 2022 году Юрай Соморовски на конференции Black Hat EU представил утилиту WS-Attacker, которая реализует алгоритм из его работы про атаки на XML-шифрование. Ссылка на презентацию тут. Я же опишу основные идеи алгоритма.

Процесс расшифровывания assertion выглядит, как это показано на рис. 17. Предположим, что для шифрования используется AES-CBC (размер блока 16 байт). Расшифрованный i-й блок Pi получается следующим образом:

Pi = Ci-1 ⨁ D(k,Ci) = Ci-1 ⨁ x

Ci-1 обозначает i-1 блок шифротекста, Ci — соответственно, i блок шифротекста. Операция расшифровывания с использованием алгоритма AES обозначена как D(k,Ci), результат этой операции обозначен как x.

Рис. 17. Операция расшифровывания assertion при помощи блочного шифра в режиме СВС
Рис. 17. Операция расшифровывания assertion при помощи блочного шифра в режиме СВС

Рассмотрим, каким образом осуществляется паддинг при XML-шифровании. Допустим, у нас есть следующий XML — <ABC/>. XML кодируется в UTF-8. То есть мы получаем следующий закодированный XML (6 байт) — 0x3c 0x41 0x42 0x43 0x2f 0x3e.

Блок шифрования для AES составляет 16 байт. Поэтому мы должны использовать 10 байт паддинга — 0x3c 0x41 0x42 0x43 0x2f 0x3e 0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 0x?? 0x0A (0x?? означает любое значение байта). Последний байт — это длина паддинга (равен 0x0A в нашем случае).

Предположим, что мы хотим расшифровать блок шифротекста Ci (без знания ключа шифрования). Мы оставляем только блоки шифротекста с номерами от 0 до i: C0, …, Ci. Далее мы модифицируем блок шифротекста Ci-1 особым образом и отправляем SAML Response приложению для расшифровки.

Наша задача — сделать такую модификацию Ci-1, чтобы при расшифровке на стороне приложения получился валидный XML и паддинг был равен одному байту (последний байт расшифрованного блока равен 0x01). Модифицированный блок Ci-1 обозначен как C~i-1.

Рис. 18. Находим модифицированное значение C(i-1)
Рис. 18. Находим модифицированное значение Ci-1

Если мы нашли C~i-1, то мы сможем вычислить последний байт Pi (или Pi[16]) расшифрованного блока (открытого текста). Сначала мы вычисляем x[16] как

x[16] = 0x01 ⨁ C~i-1[16]

И затем

Pi[16] = 0x01 ⨁ C~i-1[16] ⨁ Ci-1[16]

На следующем шаге мы получаем расшифрованное значение для остальных байтов (с 1-го по 15-й). Допустим, мы хотим вычислить Pi[3]. Для этого мы добавляем (операция XOR) C~i-1[3] различные значения (назовем их «маски») и смотрим ответ приложения — возвращается ли ошибка вследствие невалидного XML или нет.

Атаки через сжатие сообщений saml

IdP может сжимать сообщение SAML Response и затем его преобразовывать в Base64. Поэтому тестируемое приложение может ожидать, что сообщение придется распаковывать.

Используя Python, мы можем получить закодированный SAML Response (Deflate Base64) следующим образом:

Ищем уязвимости в saml sso

Самая интересная часть статьи — это какие уязвимости в реализации SAML SSO ты можешь найти на стороне приложения. Поехали.

Настраиваем saml sso в приложении

После того как мы разобрались с теорией, приступим к настройке SAML SSO для тестируемого приложения. У нас есть развернутое приложение, теперь нам нужен SAML IdP (провайдер). Я предпочитаю OneLogin, он популярен, и многие приложения его поддерживают.

Регистрируем бесплатный девелоперский аккаунт. Идем в APPS → Company Apps, затем нажимаем кнопку Add Apps. В строке поиска необходимо набрать SAML Test Connector, как показано на рис. 3. Далее выбираем SAML Test Connector (IdP w/attr).

Рис. 3. Создание тестового коннектора
Рис. 3. Создание тестового коннектора

Задаем имя для коннектора и нажимаем кнопку Save.

На стороне нашего приложения идем в настройки SAML IdP (рис. 4). Нам нужно скопировать значения полей Issuer, ACS URL, Logout URL. Эти три параметра нам генерирует приложение, и они используются для настройки коннектора на стороне IdP.

Рис. 4. Настройки SAML IdP приложения
Рис. 4. Настройки SAML IdP приложения

Параметры, которые сгенерировало приложение, необходимо перенести в настройки коннектора, как показано на рис. 5. На этом все, настройка коннектора завершена!

Рис. 5. Настройка коннектора
Рис. 5. Настройка коннектора

Переходим на вкладку SSO. Копируем значения X.509 certificate, Issuer URL, SAML Endpoint и SLO Endpoint из настроек коннектора в настройки нашего приложения (рис. 6).

Рис. 6. Параметры SSO
Рис. 6. Параметры SSO

Преобразования и цифровая подпись

Стандарт цифровой подписи в XML предусматривает различные трансформации (преобразования) XML-документа перед его подписью. У элемента <ds:Signature> есть дочерний элемент <ds:Transforms>, который содержит несколько элементов <ds:Transform>. Каждый элемент <ds:Transform> определяет одно преобразование.

Возможны следующие преобразования:

SAML IdP при формировании подписи проводит последовательность трансформаций. Проверяющая подпись сторона — наше приложение должно осуществить ту же самую последовательность преобразований в процессе проверки валидности подписи.

Заключение

Итак, ты получил представление о том, каким уязвимостям подвержены приложения с поддержкой SAML SSO. Ты узнал, каким образом настроить SSO с помощью SAML в приложении, какие инструменты использовать для тестирования безопасности SAML SSO.

Надеюсь, что теперь, если ты столкнешься с SAML SSO, будешь знать, куда копать. Успешного багхантинга!

Conclusion

You have covered how SAML authentication works, the benefits SAML provides, and how to implement SAML with Auth0 as the identity provider. If you have any questions, feel free to reach out below!

Похожее:  Сбытовая компания г. Калуга: личный кабинет на официальном сайте

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *