BurpSuite CSRF Token Tracker 实现原理与实战避坑指南

1次阅读
没有评论

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

image.webp

背景痛点

在 Web 安全测试中,CSRF Token 的动态变化常导致测试流程中断。主要表现在以下方面:

BurpSuite CSRF Token Tracker 实现原理与实战避坑指南

  • 重放攻击失败:传统工具无法自动获取最新 Token,导致请求被服务端拒绝
  • 会话状态丢失:Token 更新时若未同步处理,会触发会话失效机制
  • 测试效率低下:手动复制粘贴 Token 使测试速度下降 50%-70%

技术方案对比

方案类型 CPU 占用 内存消耗 适用场景
Session Handling Rules 低 50-100MB 简单 Token 获取场景
Extensions 中 100-200MB 复杂 DOM 解析 / 加密 Token 场景

核心实现

Token 定位策略

  1. Header 提取:适用于 Token 放在 X -CSRF-Token 等自定义头的情况

    # 示例:从响应头提取 Token
    token = response.headers.get('X-CSRF-Token')

  2. Cookie 匹配:当 Token 存储在__Secure- 前缀的 Cookie 时

    # 使用 burp 的 CookieJar 接口
    cookies = callbacks.getCookieJar(httpservice)

  3. DOM-XPath 解析:应对动态生成的 Token(最复杂场景)

    # 带重试机制的 XPath 提取
    def extract_token(html: str, xpath: str, retry=3) -> str:
        for _ in range(retry):
            try:
                doc = lxml.html.fromstring(html)
                return doc.xpath(xpath)[0]
            except Exception as e:
                time.sleep(1)
        raise ValueError("Token 提取失败")

宏配置模板

# 包含异常处理的完整宏示例
from burp import IBurpExtender, ISessionHandlingAction
import re

class BurpExtender(IBurpExtender, ISessionHandlingAction):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        callbacks.registerSessionHandlingAction(self)

    def performAction(self, current_request, macro_items):
        try:
            last_resp = macro_items[-1].getResponse()
            token = self._extract_token(last_resp)

            # 更新请求参数
            req_info = self._helpers.analyzeRequest(current_request)
            params = req_info.getParameters()
            new_params = []

            for param in params:
                if param.getName() == "csrf_token":
                    new_params.append(
                        self._helpers.buildParameter(param.getName(), 
                            token, 
                            param.getType())
                    )
                else:
                    new_params.append(param)

            new_req = self._helpers.buildRequest(req_info.getHeaders(), 
                self._helpers.buildParameters(new_params)
            )
            current_request.setRequest(new_req)

        except Exception as e:
            self._callbacks.issueAlert(f"Token 更新失败: {str(e)}")

    def _extract_token(self, response):
        # 实现多策略提取逻辑
        pass

避坑指南

案例 1:Base64 加密 Token

当遇到 Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 格式时:

  • 错误做法:直接使用 [a-zA-Z0-9]{32} 正则匹配
  • 正确方案:先 Base64 解码再提取有效载荷

案例 2:AJAX 异步加载

现象:宏执行时 Token 尚未加载完成

解决方案:

  1. 在宏设置中增加 500ms 延迟
  2. 使用 DOMContentLoaded 事件监听

案例 3:Token 绑定 IP

部分系统会校验 Token 与请求 IP 的关联性:

  • 解决方法:配置上游代理保持 IP 一致
  • 检测方法:对比不同 IP 下的 Token 变化规律

性能优化

启用 Non-UI 模式可降低 30% 资源消耗:

  1. 创建 burp_suite.vmoptions 文件
  2. 添加配置项:
    -Djava.awt.headless=true
    -Xmx512m
  3. 启动命令增加 --headless 参数

挑战任务

改造现有宏实现以下功能:

  1. 自动检测 Token 失效(通过响应状态码 403/401)
  2. 失败时自动重新触发登录流程
  3. 验证新 Token 是否成功写入请求

提示代码结构:

def check_token_valid(response: IResponseInfo) -> bool:
    """
    实现响应验证逻辑
    返回 True 表示 Token 仍有效
    """
    return response.getStatusCode() != 403

总结

通过合理配置 CSRF Token Tracker,可使测试效率提升显著。建议优先尝试 Session Handling Rules 方案,在遇到复杂场景时再考虑扩展开发。注意定期检查 Token 提取规则是否仍然有效,特别是在系统升级后。

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