2023 Black Hat | 服务器端漏洞篇之条件竞争专题
字数 2429 2025-08-10 16:34:31

服务器端漏洞之条件竞争专题教学文档

一、条件竞争基础概念

1.1 什么是条件竞争

条件竞争是一种与业务逻辑缺陷密切相关的漏洞,当网站在处理同时发来的多个请求时,会出现多个不同线程同时与相同数据交互的情况,导致应用程序出现异常行为。

1.2 竞争窗口

"竞争窗口"指可能发生碰撞的时间段,例如与数据库两次交互之间的几分之一秒。条件竞争的危害与其他逻辑漏洞相似,是与端点密切相关的。

二、条件竞争利用类型

2.1 突破限制

这是条件竞争最知名的利用类型,典型场景包括:

  • 多次使用优惠券
  • 多次兑换礼品卡
  • 对产品进行多次评价
  • 提取或转账超过账户余额的现金
  • 重复使用单个验证码
  • 绕过反暴力破解速率限制

这类攻击属于"time-of-check to time-of-use" (TOCTOU)缺陷的子类型。

2.2 突破限制的典型流程

  1. 检查用户是否使用过优惠券
  2. 将折扣应用于购买商品
  3. 在数据库中将优惠券状态修改为"已使用"

如果在窗口期内(步骤1和步骤3之间)同时发起多个请求,可以突破使用限制。

三、检测和利用条件竞争的工具与技术

3.1 Burp Suite 2023.9+新功能

  • 原生支持并发请求
  • 自动适应不同HTTP版本:
    • HTTP/1:使用末字节(last-byte)同步技术
    • HTTP/2:使用单数据包攻击技术(Black Hat USA 2023首次演示)

3.2 使用Burp Repeater

检测和利用步骤:

  1. 寻找一次性或限制请求速率的端点
  2. 连续快速多次请求该端点,测试能否突破限制
  3. 使用"Create tab group"创建请求包组
  4. 选择"Send group in parallel"并行发送请求

3.3 使用Turbo Intruder

需要满足以下条件:

  1. 目标支持HTTP/2(单包攻击与HTTP/1不兼容)
  2. 设置engine=Engine.BURP2concurrentConnections=1
  3. 使用gate参数对请求分组
  4. 使用engine.openGate()发送分组请求

示例脚本:

def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint,
                         concurrentConnections=1,
                         engine=Engine.BURP2)
    # queue 20 requests in gate '1'
    for i in range(20):
        engine.queue(target.req, gate='1')
    # send all requests in gate '1' in parallel
    engine.openGate('1')

四、条件竞争高级利用技术

4.1 隐藏的多步骤序列

许多操作背后包含多个隐藏的请求序列,用户只能看到进入序列前和得到响应两个动作,中间过程称为"子状态"。

方法论(来自PortSwigger白皮书)

  1. 预测潜在的碰撞

    • 评估端点安全性重要性
    • 判断是否有碰撞可能(需对同一条记录操作)
  2. 探寻线索

    • 进行基准测试("Send group in sequence")
    • 使用单数据包攻击测试("Send group in parallel")
    • 寻找响应变化或二阶效应
  3. 证明猜想

    • 删除多余请求确保可复现
    • 将条件竞争串联看待

4.2 多端点条件竞争

涉及同时向多个端点发送请求的条件竞争,例如:

  1. 将商品添加到购物车
  2. 付款
  3. 在强制浏览到订单确认页面前添加更多商品

对齐竞争窗口的挑战

  1. 网络架构引入的延迟
  2. 端点特定处理引入的延迟

解决方案:

  • 连接预热:通过无关请求平滑处理时间
  • 滥用速率或资源限制:触发服务器端延迟

4.3 单端点条件竞争

向单个端点发送具有不同值的并行请求可能触发条件竞争,例如:

  • 密码重置机制中存储用户ID和重置令牌
  • 电子邮件确认等基于邮件的操作

4.4 基于会话的锁定机制

某些框架(如PHP)会按顺序处理每个会话的请求,解决方案:

  • 使用不同会话令牌发送每个请求

4.5 局部构造条件竞争

多步骤创建对象可能引入可被利用的临时中间状态,例如:

  • 注册新用户时先创建用户再设置API密钥
  • 使用非标准语法传递数据结构(PHP中的param[]、Rails中的param[key])

4.6 时间敏感型攻击

利用高分辨率时间戳而非加密安全随机字符串生成安全令牌的场景,例如:

  • 仅使用时间戳随机化的密码重置令牌
  • 通过并发请求计时判断是否得到相同时间戳生成的令牌

五、防御措施

  1. 避免混合不同存储位置的数据
  2. 确保敏感端点状态更改原子化
    • 使用单个数据库事务
  3. 利用数据存储完整性和一致性功能
    • 如列唯一性约束
  4. 不要用一层数据存储保护另一层
    • 会话不适合防止数据库限制溢出攻击
  5. 确保会话处理框架保持内部一致
    • 避免单独更新会话变量
  6. 考虑无状态架构
    • 使用JWT等将状态推送到客户端

六、实战案例

6.1 突破限制条件竞争(优惠券滥用)

  1. 将商品加入购物车
  2. 拦截"Apply"促销代码请求
  3. 重复发送20个请求到Repeater
  4. 创建请求包组并并行发送
  5. 刷新购物车查看折扣叠加效果

6.2 绕过速率限制

  1. 将登录请求发送到Turbo Intruder
  2. 使用内置"race-single-packet-attack.py"模板
  3. 设置密码字段为变量位(%s)
  4. 复制密码本到剪贴板
  5. 执行攻击并发送成功响应到浏览器

6.3 多端点条件竞争(购物车)

  1. 购物车留一张礼品卡
  2. 将"添加夹克"和"结算"请求放入Repeater分组
  3. 并发发送请求
  4. 检查是否成功低价购买

6.4 单端点条件竞争(邮件确认)

  1. 准备两个不同邮箱的确认请求
  2. 确保目标邮箱(carlos@...)在第二个请求
  3. 并发发送请求
  4. 检查是否收到目标邮箱的确认邮件

6.5 局部构造条件竞争(注册机制)

  1. 发现注册仅支持特定域名邮箱
  2. 测试token参数行为
  3. 使用空值数组绕过(token[]=)
  4. 编写Turbo Intruder脚本并发注册和确认请求
  5. 使用成功注册的账号登录

6.6 时间敏感型攻击(密码重置)

  1. 并发两个密码重置请求(不同用户名)
  2. 使用两套独立会话和CSRF token
  3. 检查是否收到相同重置令牌
  4. 修改用户名为目标用户完成重置

七、总结

条件竞争是与业务逻辑密切相关的服务器端漏洞,通过精心设计的并发请求可以在竞争窗口期内突破系统限制。Burp Suite 2023.9+提供的单数据包攻击技术大大简化了检测和利用过程。防御这类漏洞需要从架构设计上消除敏感端点的子状态,确保状态更改的原子性。

服务器端漏洞之条件竞争专题教学文档 一、条件竞争基础概念 1.1 什么是条件竞争 条件竞争是一种与业务逻辑缺陷密切相关的漏洞,当网站在处理同时发来的多个请求时,会出现多个不同线程同时与相同数据交互的情况,导致应用程序出现异常行为。 1.2 竞争窗口 "竞争窗口"指可能发生碰撞的时间段,例如与数据库两次交互之间的几分之一秒。条件竞争的危害与其他逻辑漏洞相似,是与端点密切相关的。 二、条件竞争利用类型 2.1 突破限制 这是条件竞争最知名的利用类型,典型场景包括: 多次使用优惠券 多次兑换礼品卡 对产品进行多次评价 提取或转账超过账户余额的现金 重复使用单个验证码 绕过反暴力破解速率限制 这类攻击属于"time-of-check to time-of-use" (TOCTOU)缺陷的子类型。 2.2 突破限制的典型流程 检查用户是否使用过优惠券 将折扣应用于购买商品 在数据库中将优惠券状态修改为"已使用" 如果在窗口期内(步骤1和步骤3之间)同时发起多个请求,可以突破使用限制。 三、检测和利用条件竞争的工具与技术 3.1 Burp Suite 2023.9+新功能 原生支持并发请求 自动适应不同HTTP版本: HTTP/1:使用末字节(last-byte)同步技术 HTTP/2:使用单数据包攻击技术(Black Hat USA 2023首次演示) 3.2 使用Burp Repeater 检测和利用步骤: 寻找一次性或限制请求速率的端点 连续快速多次请求该端点,测试能否突破限制 使用"Create tab group"创建请求包组 选择"Send group in parallel"并行发送请求 3.3 使用Turbo Intruder 需要满足以下条件: 目标支持HTTP/2(单包攻击与HTTP/1不兼容) 设置 engine=Engine.BURP2 和 concurrentConnections=1 使用 gate 参数对请求分组 使用 engine.openGate() 发送分组请求 示例脚本: 四、条件竞争高级利用技术 4.1 隐藏的多步骤序列 许多操作背后包含多个隐藏的请求序列,用户只能看到进入序列前和得到响应两个动作,中间过程称为"子状态"。 方法论(来自PortSwigger白皮书) 预测潜在的碰撞 评估端点安全性重要性 判断是否有碰撞可能(需对同一条记录操作) 探寻线索 进行基准测试("Send group in sequence") 使用单数据包攻击测试("Send group in parallel") 寻找响应变化或二阶效应 证明猜想 删除多余请求确保可复现 将条件竞争串联看待 4.2 多端点条件竞争 涉及同时向多个端点发送请求的条件竞争,例如: 将商品添加到购物车 付款 在强制浏览到订单确认页面前添加更多商品 对齐竞争窗口的挑战 网络架构引入的延迟 端点特定处理引入的延迟 解决方案: 连接预热:通过无关请求平滑处理时间 滥用速率或资源限制:触发服务器端延迟 4.3 单端点条件竞争 向单个端点发送具有不同值的并行请求可能触发条件竞争,例如: 密码重置机制中存储用户ID和重置令牌 电子邮件确认等基于邮件的操作 4.4 基于会话的锁定机制 某些框架(如PHP)会按顺序处理每个会话的请求,解决方案: 使用不同会话令牌发送每个请求 4.5 局部构造条件竞争 多步骤创建对象可能引入可被利用的临时中间状态,例如: 注册新用户时先创建用户再设置API密钥 使用非标准语法传递数据结构(PHP中的 param[] 、Rails中的 param[key] ) 4.6 时间敏感型攻击 利用高分辨率时间戳而非加密安全随机字符串生成安全令牌的场景,例如: 仅使用时间戳随机化的密码重置令牌 通过并发请求计时判断是否得到相同时间戳生成的令牌 五、防御措施 避免混合不同存储位置的数据 确保敏感端点状态更改原子化 使用单个数据库事务 利用数据存储完整性和一致性功能 如列唯一性约束 不要用一层数据存储保护另一层 会话不适合防止数据库限制溢出攻击 确保会话处理框架保持内部一致 避免单独更新会话变量 考虑无状态架构 使用JWT等将状态推送到客户端 六、实战案例 6.1 突破限制条件竞争(优惠券滥用) 将商品加入购物车 拦截"Apply"促销代码请求 重复发送20个请求到Repeater 创建请求包组并并行发送 刷新购物车查看折扣叠加效果 6.2 绕过速率限制 将登录请求发送到Turbo Intruder 使用内置"race-single-packet-attack.py"模板 设置密码字段为变量位(%s) 复制密码本到剪贴板 执行攻击并发送成功响应到浏览器 6.3 多端点条件竞争(购物车) 购物车留一张礼品卡 将"添加夹克"和"结算"请求放入Repeater分组 并发发送请求 检查是否成功低价购买 6.4 单端点条件竞争(邮件确认) 准备两个不同邮箱的确认请求 确保目标邮箱(carlos@...)在第二个请求 并发发送请求 检查是否收到目标邮箱的确认邮件 6.5 局部构造条件竞争(注册机制) 发现注册仅支持特定域名邮箱 测试token参数行为 使用空值数组绕过( token[]= ) 编写Turbo Intruder脚本并发注册和确认请求 使用成功注册的账号登录 6.6 时间敏感型攻击(密码重置) 并发两个密码重置请求(不同用户名) 使用两套独立会话和CSRF token 检查是否收到相同重置令牌 修改用户名为目标用户完成重置 七、总结 条件竞争是与业务逻辑密切相关的服务器端漏洞,通过精心设计的并发请求可以在竞争窗口期内突破系统限制。Burp Suite 2023.9+提供的单数据包攻击技术大大简化了检测和利用过程。防御这类漏洞需要从架构设计上消除敏感端点的子状态,确保状态更改的原子性。