mcpField
B
burpsuite-project-parser

burpsuite-project-parser

github.com/trailofbits安全7.9k5.1k 次安装今天更新
代码仓库

关于 burpsuite-project-parser

用于搜索和提取 Burp Suite 项目文件数据的技能,适合分析 HTTP 流量与审计发现。它通过 Burp Suite Professional 和解析器扩展工作,并强调验证空结果以避免误报。

主要功能

  1. 01按正则搜索请求与响应数据
  2. 02提取审计发现及其严重性
  3. 03查看代理历史和站点地图
  4. 04限制输出并截断响应正文
  5. 05验证解析器扩展是否正常工作

适用场景

  1. 01查找特定响应头或正文模式
  2. 02筛选高严重性审计发现
  3. 03检查项目中的代理流量
  4. 04确认空搜索结果是否可信

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/trailofbits/skills --skill burpsuite-project-parser

安装后在 Claude Code 中输入/burpsuite-project-parser确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
assets/
trail-of-bits-mark.svg
scripts/
burp-search.sh

详细介绍

Burp 项目解析器

使用 burpsuite-project-file-parser 扩展搜索并提取 Burp Suite 项目文件中的数据。

适用场景

  • 使用正则表达式搜索响应标头或正文
  • 从 Burp 项目中提取安全审计发现
  • 导出代理历史记录或站点地图数据
  • 分析 Burp 项目文件中捕获的 HTTP 流量

前置条件

此技能将解析工作委托给 Burp Suite Professional——不会直接解析 .burp 文件。

必需项:

  1. Burp Suite Professional——必须已安装(portswigger.net)
  2. burpsuite-project-file-parser 扩展——提供 CLI 功能

安装扩展:

  1. 从 github.com/BuffaloWill/burpsuite-project-file-parser 下载
  2. 在 Burp Suite 中:Extender → Extensions → Add
  3. 选择下载的 JAR 文件

快速参考

使用包装脚本:

{baseDir}/scripts/burp-search.sh /path/to/project.burp [FLAGS]

该脚本使用环境变量以兼容不同平台:

  • BURP_JAVA:Java 可执行文件的路径
  • BURP_JAR:burpsuite_pro.jar 的路径

请检查退出代码。输出为空并不代表结果正常。 Burp 会忽略无法识别的标志,因此如果没有解析器扩展,它会正常启动并丢弃查询——这看起来和搜索没有匹配项完全一样。

退出代码含义操作
0已生成输出继续
1用法错误,或缺少文件、Java 或 JAR阅读提示信息;修正路径
3完全没有输出不要将此结果报告为“未找到任何内容”。 空结果集和未加载扩展在这里无法区分。运行下面的对照查询以判断两者
4输出不是 JSON扩展未加载,且 Burp 忽略了这些标志。请先安装扩展,再相信任何结果

任何非 0 退出代码都意味着搜索结果未经验证;仅凭该结果声称“没有匹配的流量”,属于将假阴性报告为正常结果。

解决退出码 3:控制查询

退出码 3 是最常见的情况——大多数范围很窄的正则表达式确实不会匹配任何内容——因此需要你自己执行解决步骤。你可以使用 Bash 和 Read;Burp 在此处以无头模式运行,因此没有可打开的 Extensions 选项卡,也没有可供检查的 GUI。再次运行同一查询只会再次返回 3。

改为运行控制查询:使用一个足够宽泛的选择器,如果解析器正常工作,就必须返回行;查询针对同一个项目文件。使用子组件筛选器,而不是裸选择器——控制查询仍然是查询,以上规则同样适用。

{baseDir}/scripts/burp-search.sh project.burp proxyHistory.request.headers | head -c 2000

proxyHistory.request.headers 正是合适的控制查询,因为它范围广但有界:涵盖项目中的每条记录,每条记录不到 1KB。裸 proxyHistory 也能回答同一个问题,但上面禁止使用它是有原因的——一条包含正文的记录就可能有数 MB,而 head -n 1 并不能阻止这种情况,它会完整输出其中一条记录。

控制查询结果含义操作
标准输出中有行解析器正常工作范围更窄的查询确实没有匹配到任何内容。将此作为结果报告
再次退出码 3没有返回任何内容要么扩展未加载,要么此项目不包含代理历史。确认指定的是正确的项目文件且文件非空,然后请用户确认 Burp Suite → Extensions 中是否有 burpsuite-project-file-parser
退出码 4Burp 已启动,但忽略了这些标志扩展未加载。说明这一点;不要报告流量情况

在得出任何关于项目流量的结论之前,先运行控制查询。 假设扩展已加载,正是未经验证的空结果被误认为一切正常的原因;如果控制查询无法得出结论,请用户检查 GUI 也是合理的做法。不要猜测。

通过管道运行时,退出码不是你能读取的。 管道报告的是最后一个命令的状态,而这里几乎所有示例都以 | jq、| head 或 | wc -cl 结尾——因此 $? 是 head 的 0,而不是脚本返回的 3。有两种可靠的判断方式:

  • 标准错误,无论是否使用管道,你都能看到。Error: the parser produced no output. 或 Error: Burp produced output, but not one JSON object 就是答案;没有此类信息块则表示运行正常。
  • set -o pipefail,在需要获取退出码本身时使用;或者读取 ${PIPESTATUS[0]}:
set -o pipefail
{baseDir}/scripts/burp-search.sh project.burp auditItems | jq -c 'select(.severity == "High")'
echo "exit: $?"

非 JSON 输出永远不会进入标准输出,因此下游的 grep 或 jq 不会匹配到 Burp 启动横幅并将其误认为数据。

设置说明请参阅平台配置。

子组件筛选器(请使用这些筛选器)

始终使用子组件筛选器,而不是完整转储。 完整的 proxyHistory 或 siteMap 可能返回数 GB 的数据。子组件筛选器只返回所需内容。

可用筛选器
筛选器返回内容典型大小
proxyHistory.request.headers仅请求行和标头小(每条记录 < 1KB)
proxyHistory.request.body仅请求正文不定
proxyHistory.response.headers仅状态和标头小(每条记录 < 1KB)
proxyHistory.response.body响应正文很大——请避免
siteMap.request.headers网站地图中的同类内容小
siteMap.request.body不定
siteMap.response.headers小
siteMap.response.body很大——请避免
默认方法

从标头开始,而不是正文:

# GOOD - headers only, safe to retrieve
{baseDir}/scripts/burp-search.sh project.burp proxyHistory.request.headers | head -c 50000
{baseDir}/scripts/burp-search.sh project.burp proxyHistory.response.headers | head -c 50000

# BAD - full records include bodies, can be gigabytes
{baseDir}/scripts/burp-search.sh project.burp proxyHistory  # NEVER DO THIS

只有在检查标头后,才针对特定 URL 获取正文,并且始终要截断:

# 1. First, find interesting URLs from headers
{baseDir}/scripts/burp-search.sh project.burp proxyHistory.response.headers | \
  jq -r 'select(.headers | test("text/html")) | .url' | head -n 20

# 2. Then search bodies with targeted regex - MUST truncate body to 1000 chars
{baseDir}/scripts/burp-search.sh project.burp "responseBody='.*specific-pattern.*'" | \
  head -n 10 | jq -c '.body = (.body[:1000] + "...[TRUNCATED]")'

硬性规则:超过 1000 个字符的正文内容绝不能进入上下文。 如果用户需要完整的正文内容,必须在 Burp Suite 的 UI 中查看。

正则表达式搜索操作

搜索响应标头
responseHeader='.*regex.*'

搜索所有响应标头。输出:{"url":"...", "header":"..."}

示例——查找服务器特征标识:

responseHeader='.*(nginx|Apache|Servlet).*' | head -c 50000
搜索响应正文
responseBody='.*regex.*'

必须:正文内容始终截断至最多 1000 个字符。 每个响应正文都可能有数 MB。

# REQUIRED format - always truncate .body field
{baseDir}/scripts/burp-search.sh project.burp "responseBody='.*<form.*action.*'" | \
  head -n 10 | jq -c '.body = (.body[:1000] + "...[TRUNCATED]")'

切勿检索完整正文内容。 如果需要查看某个特定响应的更多内容,请让用户在 Burp Suite 的 UI 中打开它。

其他操作

提取审计项
auditItems

返回所有安全发现。输出包括:名称、严重性、置信度、主机、端口、协议、URL。

注意: 审计项很小(不包含正文),使用 head -n 100 检索是安全的。

导出代理历史记录(避免)
proxyHistory

切勿直接使用此命令。 请改用子组件筛选器:

  • proxyHistory.request.headers
  • proxyHistory.response.headers
导出站点地图(避免)
siteMap

切勿直接使用此命令。 请改用子组件筛选器。

输出限制(必需)

重要:检索数据前始终先检查结果大小。 宽泛的搜索可能返回数千条记录,每条都可能有数 MB。这会导致上下文窗口溢出。

第 1 步:始终先检查大小

执行任何搜索前,检查记录数和字节数:

# Check record count AND total bytes - never skip this step
{baseDir}/scripts/burp-search.sh project.burp proxyHistory | wc -cl
{baseDir}/scripts/burp-search.sh project.burp "responseHeader='.*Server.*'" | wc -cl
{baseDir}/scripts/burp-search.sh project.burp auditItems | wc -cl

wc -cl 的输出显示:<bytes> <lines>(例如,524288 42 表示 42 条记录共 512KB)。

解读结果——两项指标都必须达标:

指标安全缩小搜索范围过于宽泛停止
行数< 5050-200200+1000+
字节数< 50KB50-200KB200KB+1MB+

单个 10MB 响应若位于一行中,会显示较高的字节数,但行数只有 1——字节数检查可以发现这种情况。

wc -cl 输出 0 0 并不代表可以据此采取行动的大小——脚本以状态码 3 退出,且未验证任何内容。管道会隐藏这一情况,因此请单独重新运行查询,并读取退出码,然后再得出项目中没有匹配流量的结论。

第 2 步:缩小宽泛搜索的范围

如果记录数或大小过高:

  1. 使用子组件筛选器(见上表):

    # Instead of: proxyHistory (gigabytes)
    # Use: proxyHistory.request.headers (kilobytes)
    
  2. 缩小正则表达式模式的范围:

    # Too broad (matches everything):
    responseHeader='.*'
    
    # Better - target specific headers:
    responseHeader='.*X-Frame-Options.*'
    responseHeader='.*Content-Security-Policy.*'
    
  3. 检索前使用 jq 进行筛选:

    # Get only specific content types
    {baseDir}/scripts/burp-search.sh project.burp proxyHistory.response.headers | \
      jq -c 'select(.url | test("/api/"))' | head -n 50
    
第 3 步:始终截断输出

即使缩小了搜索范围,也始终通过截断来限制输出:

# ALWAYS use head -c to limit total bytes (max 50KB)
{baseDir}/scripts/burp-search.sh project.burp proxyHistory.request.headers | head -c 50000

# For body searches, truncate each JSON object's body field:
{baseDir}/scripts/burp-search.sh project.burp "responseBody='pattern'" | \
  head -n 20 | jq -c '.body = (.body | if length > 1000 then .[:1000] + "...[TRUNCATED]" else . end)'

# Limit both record count AND byte size:
{baseDir}/scripts/burp-search.sh project.burp auditItems | head -n 50 | head -c 50000

必须执行的硬性限制:

  • 对所有输出使用 head -c 50000(最多 50KB)
  • 将 .body 字段截断至 1000 个字符——必须执行,无例外
    jq -c '.body = (.body[:1000] + "...[TRUNCATED]")'
    

未经计数且未截断时,切勿运行以下命令:

  • proxyHistory / siteMap(完整导出——始终使用子组件筛选器)
  • responseBody='...' 搜索(正文可能各有数 MB)
  • 任何宽泛的正则表达式,例如 .* 或 .+

调查工作流

  1. 确定范围——你要查找什么?(特定漏洞类型、端点、标头模式)

  2. 先搜索审计项——从 Burp 的发现开始:

    {baseDir}/scripts/burp-search.sh project.burp auditItems | jq 'select(.severity == "High")'
    
  3. 检查置信度分数——筛选出可采取行动的发现:

    ... | jq 'select(.confidence == "Certain" or .confidence == "Firm")'
    
  4. 提取受影响的 URL——了解攻击面:

    ... | jq -r '.url' | sort -u
    
  5. 搜索原始流量以了解上下文——检查实际请求和响应:

    {baseDir}/scripts/burp-search.sh project.burp "responseBody='pattern'"
    
  6. 手动验证——Burp 的发现只是线索,并非证据。请逐项验证。

理解结果

严重性与置信度

Burp 会同时报告严重性(高/中/低)和置信度(确定/可信/暂定)。进行分类处理时两者都要参考:

组合含义
高 + 确定很可能是真实漏洞,应优先调查
高 + 暂定通常是误报,报告前请先验证
中 + 可信值得调查,可能需要手动验证

“高严重性、暂定置信度”的发现通常是误报。不要仅根据严重性报告发现。

代理历史记录不完整时

代理历史记录仅包含 Burp 捕获的内容。以下情况可能会导致流量缺失:

  • 范围筛选器排除了域名
  • 拦截设置丢弃了请求
  • 浏览器流量未经过 Burp 代理

如果未找到预期流量,请检查原始项目中的 Burp 范围和代理设置。

HTTP 正文编码

响应正文可能采用 gzip 压缩、分块传输,或使用非 UTF-8 编码。适用于纯文本的正则表达式在编码后的响应中可能会悄然失效。如果搜索结果少于预期:

  • 检查响应是否经过压缩
  • 尝试更宽泛的模式,或先搜索标头
  • 使用 Burp 的 UI 检查原始响应与渲染后的响应

应拒绝的自我安慰

导致遗漏漏洞或误报的常见捷径:

捷径为什么不对
“这个正则表达式看起来不错”先用样本数据验证——编码和转义可能导致悄然失效
“严重性高 = 必须修复”也要查看置信度评分;Burp 会产生误报
“所有审计项都相关”根据实际威胁模型进行筛选;并非每个发现都适用于每个应用
“代理历史记录是完整的”Burp 的范围/拦截设置可能会对其进行筛选;你只能看到 Burp 捕获的内容
“Burp 发现了问题,所以它就是漏洞”Burp 的发现需要手动验证——它们表示潜在问题,而非确凿证据
“搜索没有返回结果,所以流量不存在”先检查退出码。退出码 3 表示脚本无法区分结果为空还是扩展程序未加载,退出码 4 表示查询根本没有运行。只有退出码 0 才能说明“未找到内容”是针对项目而言,而非工具本身

输出格式

所有输出均为 JSON,每行一个对象。通过 jq 格式化:

{baseDir}/scripts/burp-search.sh project.burp auditItems | jq .

使用 grep 筛选:

{baseDir}/scripts/burp-search.sh project.burp auditItems | grep -i "sql injection"

示例

搜索 CORS 标头(限制字节数):

{baseDir}/scripts/burp-search.sh project.burp "responseHeader='.*Access-Control.*'" | head -c 50000

获取所有高严重性发现(审计项很少,但仍需限制数量):

{baseDir}/scripts/burp-search.sh project.burp auditItems | jq -c 'select(.severity == "High")' | head -n 100

仅从代理历史记录中提取请求 URL:

{baseDir}/scripts/burp-search.sh project.burp proxyHistory.request.headers | jq -r '.request.url' | head -n 200

搜索响应正文(必须将正文截断为 1000 个字符):

{baseDir}/scripts/burp-search.sh project.burp "responseBody='.*password.*'" | \
  head -n 10 | jq -c '.body = (.body[:1000] + "...[TRUNCATED]")'

平台配置

包装脚本需要两个环境变量,以定位 Burp Suite 捆绑的 Java 和 JAR 文件。

macOS
export BURP_JAVA="/Applications/Burp Suite Professional.app/Contents/Resources/jre.bundle/Contents/Home/bin/java"
export BURP_JAR="/Applications/Burp Suite Professional.app/Contents/Resources/app/burpsuite_pro.jar"
Windows
$env:BURP_JAVA = "C:\Program Files\BurpSuiteProfessional\jre\bin\java.exe"
$env:BURP_JAR = "C:\Program Files\BurpSuiteProfessional\burpsuite_pro.jar"
Linux
export BURP_JAVA="/opt/BurpSuiteProfessional/jre/bin/java"
export BURP_JAR="/opt/BurpSuiteProfessional/burpsuite_pro.jar"

将这些导出语句添加到 shell 配置文件(.bashrc、.zshrc 等),以便持久生效。

手动调用

如果不使用包装脚本,可直接调用:

"$BURP_JAVA" -jar -Djava.awt.headless=true "$BURP_JAR" \
  --project-file=/path/to/project.burp [FLAGS]

评论

支持 Markdown