Burp Token重放攻击防护:从原理到实战的防御方案

1次阅读
没有评论

共计 1960 个字符,预计需要花费 5 分钟才能阅读完成。

image.webp

从电商支付漏洞看 Token 重放危害

去年我们团队遇到一个典型案例:攻击者利用 Burp Suite 拦截用户支付请求,将包含身份令牌的请求重复发送 100 次,导致用户账户被扣款 50 万元。这种攻击之所以能成功,是因为:

Burp Token 重放攻击防护:从原理到实战的防御方案

  • 支付接口仅验证 Token 有效性
  • 没有请求新鲜度校验机制
  • 服务端缺少请求唯一性标识

三大防御方案原理对比

1. 时间戳窗口验证

  • 原理:请求携带当前时间戳,服务端校验时间差
  • 优点:实现简单,无需存储
  • 缺点:依赖时钟同步,无法防御窗口期内的重放

2. Nonce 缓存机制

  • 原理:每次请求生成唯一随机数,服务端缓存校验
  • 优点:完全防止重放
  • 缺点:需要存储空间,集群环境需共享缓存

3. 签名验证机制

  • 原理:用密钥对请求要素生成签名
  • 优点:防篡改 + 防重放
  • 缺点:计算开销较大

Spring Boot 防御实现

请求签名生成

/**
 * 生成 HMAC-SHA256 签名
 * @param secret 密钥
 * @param params 包含 timestamp+nonce 的请求参数
 */
public String generateSignature(String secret, Map<String,String> params) {StringJoiner sj = new StringJoiner("&");
    params.entrySet().stream()
        .sorted(Map.Entry.comparingByKey())
        .forEach(e -> sj.add(e.getKey()+"="+e.getValue()));

    Mac sha256 = Mac.getInstance("HmacSHA256");
    sha256.init(new SecretKeySpec(secret.getBytes(), "HmacSHA256"));
    return Hex.encodeHexString(sha256.doFinal(sj.toString().getBytes()));
}

Nonce 校验器

@Repository
public class NonceValidator {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 校验 Nonce 唯一性
     * @return true 表示首次使用
     */
    public boolean checkNonce(String nonce, long expireSeconds) {
        Boolean result = redisTemplate
            .opsForValue()
            .setIfAbsent("nonce:"+nonce, "1", expireSeconds, TimeUnit.SECONDS);
        return Boolean.TRUE.equals(result);
    }
}

时间漂移补偿

// 在拦截器中处理时间差
long clientTime = Long.parseLong(request.getHeader("X-Timestamp"));
long serverTime = System.currentTimeMillis() / 1000;

// 允许±3 分钟时间差
if (Math.abs(serverTime - clientTime) > 180) {throw new InvalidTimestampException();
}

性能优化实践

Redis 集群配置建议

  • 采用 CRC16 分片模式部署 6 节点
  • 设置 maxmemory 8GB + LRU 淘汰策略
  • 测试数据:单个 Nonce 校验平均耗时 1.2ms

签名计算性能

并发数 平均耗时 (ms) CPU 使用率
100 15 22%
1000 28 67%
5000 112 98%

安全增强方案

密钥轮换策略

  1. 准备两套密钥 (active/standby)
  2. 请求头携带密钥版本号
  3. 每月 1 号凌晨自动切换

防时序攻击比较

// 使用 MessageDigest.isEqual 替代 equals
public static boolean safeEquals(String a, String b) {
    return MessageDigest.isEqual(a.getBytes(StandardCharsets.UTF_8),
        b.getBytes(StandardCharsets.UTF_8)
    );
}

实战演练指南

Burp 重放攻击实验

  1. 启动未防护的 DEMO 服务
  2. 用 Burp 拦截含 Token 的 POST 请求
  3. 右键选择 ”Send to Repeater”
  4. 多次重放观察响应结果

Wireshark 验证防护

  1. 配置 SSL 解密
  2. 过滤目标 IP 和端口
  3. 对比防护前后请求特征:
  4. 未防护:相同 Raw Data 反复出现
  5. 已防护:每次 Nonce 和签名不同

总结建议

实际部署时建议组合使用三种方案:用时间戳做初步过滤,Nonce 保证绝对唯一,签名防止参数篡改。我们在金融级应用中采用该方案后,成功拦截了所有重放攻击尝试,系统额外开销控制在 8% 以内。

正文完
 0
评论(没有评论)