> 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/race-conditions/exploitation-of-time-sensitive-vulnerabilities.md).

# 时间敏感型漏洞利用

面向 PortSwigger Web Security Academy 实验室的时间敏感型漏洞利用笔记，包括利用流程、载荷测试、Burp Suite 验证和修复背景。

### 利用时间敏感漏洞

### 实验环境

该网站提供一个……功能 **重置密码** 通过电子邮件发送的链接。/ 在逻辑应用层面并不存在真正的竞态条件，但……的生成 **令牌** 是 **分情况处理的**：它取决于一个 **可预测的值** （时间），这使得可以通过\*\*同时\*\*发送请求来伪造另一个用户的有效令牌。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-c58a84bf71f02dd10b85375f3d415c416bce37ea%2F%7BDF7E5660-9207-4CDB-B974-C67123A4191D%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

### 初步观察

1. 我们使用 **忘记密码** 与用户 `wiener`.

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-626227ff5ce7b6028baaf462af347a06ca8fd1cf%2F%7BB837963E-072E-48E3-B684-700364BE996A%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

* 一封包含以下类型链接的电子邮件：
* `/forgot-password?user=wiener&token=<token>`

{% code overflow="wrap" %}

```bash
你好！

请点击下面的链接重置你的密码。

https://0a1300c9040343bf810b7f2a00e60085.web-security-academy.net/forgot-password?user=wiener&token=3930dc6d3d076151204ad4147326f81a5e1609a8
```

{% endcode %}

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-a26e0e7d9ed5174051929e952e4701fbf0c31666%2F%7B113509E4-671D-401B-8EA0-F6AE9725AB1E%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

* 令牌看起来像一个 **SHA1** （40个十六进制字符）。

`forgot-password?user=wiener&token=3930dc6d3d076151204ad4147326f81a5e1609a8`

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-930b5c1465387f7d158ca316aa89aa6512b44d48%2F%7BB66B464D-4E68-4DAB-BEEC-0A8D7F05E9A5%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

* 令牌看起来像一个 **SHA1** （40个十六进制字符）。

```bash
hashid '3930dc6d3d076151204ad4147326f81a5e1609a8'
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-b340c74876dd768b3c7c3d51ff402645274e0abb%2F%7B4BC8DA5A-DA34-4C1C-9B18-9B2014CD516F%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

1. 通过生成多个令牌

假设：令牌主要由一个 **时间戳** （或者一个基于时间的值）派生，而不是一个强随机密钥。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-5c3e7d33579f6ed4584f7ebc7de1cde1e72139d4%2F%7B178FE46D-40F0-4953-A695-CB87823E2810%7D.png?alt=media" alt="" width="563"><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-bec565b7f22d7983fb35e5825b4630f0ab626d2a%2F%7B12B696E9-90B1-4254-9667-9BE6B0B5A8A1%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

问题：服务器（PHP）有时会通过相同的会话/CSRF来避免冲突。/ 解决方案：获取 **两个独立会话**.

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-2ee71deeee62f0504694e71a121ce2e6c5d653b1%2F%7BFEB5680C-2F57-42E6-B7C8-FF2B83D48C79%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

### 准备：获取两组会话 + CSRF 对

向以下地址分别发送两个请求：

* `GET /forgot-password`

```http
GET /forgot-password HTTP/2
Host: 0a1300c9040343bf810b7f2a00e60085.web-security-academy.net
Cookie:
```

每个响应都会给出一组新的配对：

* `PHPSESSID=<...>`
* 新的 CSRF 令牌（值隐藏在表单中）

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-b60d532445a46566acaa6178aab35384c8538fa7%2F%7B98B7B0DE-2B48-4BED-8144-C012C86D110E%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

有 **两个已准备好的请求**，每个都带有：

* 其 `PHPSESSID` cookie
* 其关联的 CSRF 字段

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-f3e9ec62d0b0ff2b38e6b310296c91946facabb9%2F%7BE079B013-0BBB-45D5-82A6-61EA24021EB4%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

### 触发：并行发送

然后我们并行发送 **并行地** 两个重置的 POST 请求（相同端点），在 Burp 中（分组 + 并行发送），使它们到达 **在同一时间窗口内**.

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-1639be135577b23a01cc8c769db888ffb9427bd9%2F%7B73C6239F-A361-47DD-9C21-B14A292C373F%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

观察到的结果：收到的两封邮件包含\*\*完全相同的令牌\*\*：

```bash
933ccbd314dc37df95887cd914b07e330517f7bb
933ccbd314dc37df95887cd914b07e330517f7bb
```

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-6e01ba6eb1ee900953b12829b07e9dce10948360%2F%7BB899DE0C-EB53-4923-BF3D-9D085BD0D5C9%7D.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-a02641ffd57f018d7f18479178fe15dcb54edee5%2F%7B792B8500-D851-4581-94E5-A377EB809957%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

### 操作：用 Wiener 的令牌重置 Carlos

目标：对 `carlos`.

方法：

1. 并行启动两个重置：

* 一个用于 `wiener`
* 一个用于 `carlos`

```bash
forgot-password?user=wiener&token=da1d6e3ed67bef3efa9fe74fcfbf7603120ea744
forgot-password?user=carlos&token=da1d6e3ed67bef3efa9fe74fcfbf7603120ea744
```

由于令牌相同，收到的令牌（例如通过 `wiener` 电子邮件）也将对……有效 `carlos`.

如果该网站接受这个 URL，你就可以 **设置新密码** 用于 `carlos`.

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-f516708a8f594fc919108cb151310a273c478af2%2F%7BDCB16AF0-DCAB-499F-A6BF-EF1784E72D57%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

### 实验完成

1. 以……身份登录 `carlos` 使用新密码。
2. 访问\*\*管理员登录\*\*。
3. 删除 `carlos` 用户以验证实验。

<figure><img src="https://1574813340-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-3b7b12ddd7f01c59ee5b83b2f2b93214ec5bbd08%2F%7B686872ED-506C-438E-94DB-7ED0530354C1%7D.png?alt=media" alt=""><figcaption></figcaption></figure>


---

# 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/race-conditions/exploitation-of-time-sensitive-vulnerabilities.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.
