第4章 Burp Suite Extender 插件开发

使用Java编写自定义扩展 · 加载Python插件 · 调用Burp API · 注册自定义Tab

4.1 插件开发概述

Burp Suite Extender 是 Burp 生态中最强大的扩展点,允许安全测试人员通过 Java 或 Python (Jython) 编写自定义逻辑,深度集成到代理、扫描器、Repeater 等组件中。本章将带你从零构建一个具备实用价值的扩展,涵盖 Java 扩展骨架、Python 插件加载、核心 API 调用以及自定义 UI Tab 的注册。

Java 扩展 Python 插件 Burp API 自定义 Tab Extender 加载桥接 Burp Suite 内核

4.2 使用 Java 编写自定义扩展

Burp 扩展基于 IBurpExtender 接口,所有 Java 扩展必须实现此接口。推荐使用 Gradle 或 Maven 管理依赖,打包为 JAR 文件。

核心接口与类

接口 / 类用途
IBurpExtender扩展入口,必须实现 registerExtenderCallbacks
IExtensionHelpers辅助方法,如构建请求、解析响应
IHttpListener监听 HTTP 请求/响应,可修改流量
ITab自定义 UI 标签页
💡 最佳实践: 使用 callbacks.setExtensionName() 命名扩展,并在 registerExtenderCallbacks 中注册所有监听器。
IBurpExtender registerExtenderCallbacks callbacks 通过 callbacks 注册 IHttpListener / ITab 等
// 最小 Java 扩展骨架
import burp.api.montoya.BurpExtension;
import burp.api.montoya.MontoyaApi;

public class DemoExtension implements BurpExtension {
    @Override
    public void initialize(MontoyaApi api) {
        api.extension().setName("Demo Extension");
        api.logging().logToOutput("扩展已加载!");
        // 注册自定义 Tab
        api.userInterface().registerSuiteTab("Demo Tab", new DemoPanel());
    }
}

4.3 加载 Python 插件 (Jython)

Burp 通过 Jython 解释器支持 Python 扩展。需在 Extender → Options 中设置 Jython JAR 路径。Python 插件同样实现 IBurpExtender 接口(Python 风格)。

Python 脚本 .py Jython 解释器 Burp API Extender → Add → 选择 Python 文件
# Python 扩展示例 (demo.py)
from burp import IBurpExtender, IHttpListener

class BurpExtender(IBurpExtender, IHttpListener):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        callbacks.setExtensionName("Python Demo")
        callbacks.registerHttpListener(self)
        print("[+] Python 扩展加载成功")

    def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
        if messageIsRequest:
            print("[*] 拦截到请求: " + messageInfo.getUrl().toString())

4.4 调用 Burp API 核心能力

Burp 提供 Montoya API (新版) 和 传统 API (IBurpExtender)。常用 API 包括:

  • HTTP 流量劫持:IHttpListener 修改请求/响应
  • Scanner 集成:IScannerCheck 自定义扫描检查
  • Intruder 载荷:IIntruderPayloadGenerator 生成自定义字典
  • 日志与输出:callbacks.printOutput() / printError()
IHttpListener IScannerCheck processHttpMessage doPassiveScan / doActiveScan 修改请求头 添加标记 漏洞检测
// 使用 Montoya API 修改响应
api.http().registerHttpHandler(new HttpHandler() {
    @Override
    public void handleHttpRequest(HttpRequestToBeSent request) {
        // 在请求中添加自定义头
        request.setHeader("X-Burp-Extension", "true");
    }
    @Override
    public void handleHttpResponse(HttpResponseReceived response) {
        // 记录响应状态码
        api.logging().logToOutput("状态码: " + response.statusCode());
    }
});

4.5 注册自定义 Tab

通过 ITab 接口或 Montoya API 的 registerSuiteTab 方法,可以在 Burp UI 中添加自己的标签页,用于展示扫描结果、配置面板或实时数据。

自定义 JPanel / JTab registerSuiteTab Burp UI Tab 标题 + 组件实例 例如: "My Scanner"
// Java 注册自定义 Tab (Montoya API)
import burp.api.montoya.ui.UserInterface;

UserInterface ui = api.userInterface();
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JLabel("自定义扩展面板", SwingConstants.CENTER));
ui.registerSuiteTab("扩展工具", panel);

// 传统 API 方式
public class MyTab implements ITab {
    @Override
    public String getTabCaption() { return "My Tab"; }
    @Override
    public Component getUiComponent() { return new JLabel("Hello"); }
}
callbacks.addSuiteTab(new MyTab());

4.6 实战:构建一个请求日志插件

结合以上知识点,开发一个记录所有 HTTP 请求的扩展,并在自定义 Tab 中实时显示。

🔧 实现步骤: ① 实现 BurpExtension ② 注册 HttpHandler ③ 使用 Swing 的 DefaultListModel 存储请求 ④ 注册 Suite Tab 展示 JList。
// 请求日志扩展核心片段
public class RequestLogger implements BurpExtension {
    private DefaultListModel<String> logModel = new DefaultListModel<>();
    
    @Override
    public void initialize(MontoyaApi api) {
        api.extension().setName("Request Logger");
        JList<String> logList = new JList<>(logModel);
        api.userInterface().registerSuiteTab("日志", new JScrollPane(logList));
        
        api.http().registerHttpHandler(new HttpHandler() {
            @Override
            public void handleHttpRequest(HttpRequestToBeSent request) {
                logModel.addElement("[REQ] " + request.url());
            }
            @Override
            public void handleHttpResponse(HttpResponseReceived response) {
                logModel.addElement("[RES] " + response.initiatingRequest().url());
            }
        });
    }
}