当前位置: 首页 > ops >正文

BurpSuite Montoya API 详解

文章目录

  • 前言
  • 1. API 结构
    • 1.1 概述
    • 1.2 API文件源码解析
  • 2. BurpExtension 接口
  • 3. MontoyaApi接口
  • 4. package burp.api.montoya.proxy
    • 4.1 Proxy 接口
    • 4.2 ProxyRequestHandler接口
    • 4.3 Demo
  • 5. BurpSuite burpSuite()
  • 6. Extension extension()
  • 7. Http http()
  • 参考

前言

我们已经学习了什么是burp扩展、怎么开发一个简单的burp扩展,现在是时候深入学习Montoya API 来帮助我们开发出一个实用的burp扩展。本文基于Montoya API 2025.4.x(对应burpsuite2025.4.x版本),介绍其内部结构及常用方法。


1. API 结构

1.1 概述

Montoya API 是 Burp Suite 的扩展接口,通过模块化设计提供丰富的功能。模块化扩展点:每个功能(如Proxy拦截、Scanner检查)以独立模块形式暴露,开发者按需调用。其核心结构分为以下模块:

  1. 基础模块
    • BurpExtension(扩展入口,包含初始化方法 initialize(MontoyaApi api),用于注入 API 实例,即实现initialize方法,其参数MontoyaApi由burp传入,通过MontoyaApi访问burp提供的服务)
    • MontoyaApi,提供访问 Burp 各模块的入口,例如:
      • burpSuite():访问 Burp 应用级功能(如导出配置、关闭 Burp)。
      • collaborator():操作 Collaborator 模块(生成反连 payload)。
      • comparer():数据比对功能。
      • http():HTTP 请求/响应处理。
      • extension():插件管理功能(如注册事件监听器)。
  2. 功能模块
    在这里插入图片描述

1.2 API文件源码解析

montoya-api-2025.4.jarjar包里主要是一大堆接口,这些接口定义了burp提供的服务,也就是通过调用接口里的方法,控制brup可以做什么。

去到官方文档的首页,是MontoyaApi接 口,罗列了一大堆接口规定的方法(函数)。
在这里插入图片描述
我们再打开SDK,会发现文件夹几乎就对应上面的方法。实际上,调用上面的方法,都是返回一个相应的对象,这些对象的结构声明就在对应的文件夹下的文件里。
在这里插入图片描述

我们从扩展的入口BurpExtension接口开始,进入MontoyaApi接口,接着到 MontoyaApi 对象方法里可实例化的各个接口,逐步剖析整套 MontoyaAPI SDK。

2. BurpExtension 接口

API doc
在这里插入图片描述
相应的翻译也在图片里注明了,这个接口很简单,写一个类implements这个接口,并实现其中的initialize(Montoya api)方法即可。
需要注意的是,我们常说要运行程序必须要有一个main方法,一个程序只能有一个main方法,扩展的main方法在哪?主方法在BurpSuite里,扩展由burp调用,MontoyaApi对象则由bp的主程序传进来。

public class HelloBurp implements BurpExtension {// 实现实现该方法@overridevoid initialize(MontoyaApi api) {
/* 加载插件时调用此方法,我们可以在这里写逻辑代码,我们可以写点什么?依靠主程序传入的 MontoyaApi 类型对象,做点什么那么就需要看 MontoyaApi 这个类型提供了什么
*/

3. MontoyaApi接口

前面我们说了,burp中每个功能(如Proxy拦截、Scanner检查)以独立模块形式暴露,开发者按需调用。具体的实现方式就是通过MontoyaApi中的方法获取对应的模块对象。
在这里插入图片描述
那么,接下来的任务就是学习各个模块接口。那么多接口,该怎么学习呢?哪些是主要的接口,有没有一条线索将主要的接口串联起来?

我们回归本质:Burp的核心是能够在模块之间传递 HTTP 请求以执行特定任务的能力。那我们以Http数据包为线索,主要学习的方向就是:

  • Http数据包的来源与发送
  • Http数据包对象
  • 模块之间数据包的传递

4. package burp.api.montoya.proxy

一般情况下,我们都是通过代理浏览器的HTTP流量获得HTTP数据包进行测试。可以确定,,代理模块Proxy中必然会产生HTTP请求的流量,我们通过跟踪一个HTTP请求,学习Montoya API 提供给我们的接服务能力。

包结构如下,这个包定义我们在 Proxy UI界面看到的、可控制的大部分功能。
在这里插入图片描述

4.1 Proxy 接口

burp中proxy模块的抽象。回顾proxy中的主要功能:

  • 捕获流量(intercept on | off、forward、drop)
  • Http history

对应的,Proxy接口的主要方法如下:

public interface Proxy {void enableIntercept(); 	// 设置 intercept onvoid disableIntercept();	// 设置 intercept offboolean isInterceptEnabled();	// 获取 intercept 状态List<ProxyHttpRequestResponse> history();Registration registerRequestHandler(ProxyRequestHandler handler);Registration registerResponseHandler(ProxyResponseHandler handler);
}

List<ProxyHttpRequestResponse> history();,对应图形界面中的HTTP history tab。该方法返回一个List<ProxyHttpRequestResponse>,代表http的历史记录,List<ProxyHttpRequestResponse>中的一个ProxyHttpRequestResponse对象,即表示tab中的一行记录。
在这里插入图片描述


Registration registerRequestHandler(ProxyRequestHandler handler);,学过GUI(图形用户接口)编程的师傅应该对这个方法感到熟悉,handler、注册handler,这是事件驱动编程中常用的术语,这里我们不关心什么是事件驱动编程(请问deepseek),只需要知道构造一个ProxyRequestHandler类型的对象,并将其传给registerRequestHandler(),当proxy中捕获到流量时,就会通知handler,调用handler里面的方法。

4.2 ProxyRequestHandler接口

我们来看一下ProxyRequestHandler.class

public interface ProxyRequestHandler {ProxyRequestReceivedAction handleRequestReceived(InterceptedRequest interceptedRequest);ProxyRequestToBeSentAction handleRequestToBeSent(InterceptedRequest interceptedRequest);
}

1. ProxyRequestHandler接口中又涉及的接口角色与职责:

接口作用触发阶段
InterceptedRequest表示被代理拦截的 原始请求,包含未经修改的请求数据(如 URL、头、体)。代理首次捕获到客户端请求时生成。
ProxyRequestReceivedAction定义代理对拦截请求的 处理动作(如放行、拦截、丢弃)。在请求被代理接收后、发送到服务器前触发。
ProxyRequestToBeSentAction定义代理对即将发送的请求的 最终处理动作(如修改后发送、取消发送)。在请求经过处理后、即将发送到服务器前触发。

终于看到Http流量的来源了,其被封装为一个InterceptedRequest类型的对象,并传给了两个方法,方法会在不同阶段被自动调用(事件驱动编程)。跟踪Http请求的流转,不就是查看这些方法之间的调用顺序,也是在这些方法里实现我们对Http请求的处理逻辑(增删改)。


2. 处理流程与协作关系

阶段 1:请求拦截(InterceptedRequest

  • 触发条件:客户端(如浏览器)通过 Burp 代理发送请求,代理捕获到该请求。
  • 数据载体InterceptedRequest 对象包含原始请求的完整信息。
  • 扩展操作:通过实现 ProxyHttpRequestHandlerhandleRequestReceived() 方法处理该对象:
    public ProxyRequestReceivedAction handleRequestReceived(InterceptedRequest interceptedRequest) {// 分析或修改请求if (interceptedRequest.url().contains("admin")) {// 拦截敏感请求并标记为待处理return ProxyRequestReceivedAction.intercept(interceptedRequest);}// 直接放行非敏感请求return ProxyRequestReceivedAction.continueWith(interceptedRequest);
    }
    

阶段 2:处理动作决策(ProxyRequestReceivedAction

  • 动作类型
    • continueWith(request):放行请求(可选传入修改后的请求)。
    • intercept(request):拦截请求并等待用户操作(通过 Burp UI)。
    • drop():直接丢弃请求。
  • 示例
    // 修改请求头后放行
    InterceptedRequest modifiedRequest = interceptedRequest.withHeader("X-Token", "123");
    return ProxyRequestReceivedAction.continueWith(modifiedRequest);
    

阶段 3:发送前最终处理(ProxyRequestToBeSentAction

  • 触发条件:请求经过 ProxyRequestReceivedAction 处理后决定放行。
  • 数据载体InterceptedRequest 对象(包含可能已被修改的请求)。
  • 扩展操作:通过实现 ProxyHttpRequestHandlerhandleRequestToBeSent() 方法进行最终调整:
    public ProxyRequestToBeSentAction handleRequestToBeSent(InterceptedRequest interceptedRequest) {// 添加请求头HttpRequest modifiedRequest = interceptedRequest.withHeader("X-Author", "MingSec");// 继续发送修改后的请求return ProxyRequestToBeSentAction.continueWith(modifiedRequest);
    }
    

3. 核心交互流程

客户端 Burp Proxy 扩展插件 目标服务器 User 发送请求 生成 InterceptedRequest 返回 ProxyRequestReceivedAction 生成 HttpRequestToBeSent 返回 ProxyRequestToBeSentAction 发送最终请求 在 UI 中显示拦截请求 手动修改并放行 生成 HttpRequestToBeSent 返回 ProxyRequestToBeSentAction 发送最终请求 终止流程,不发送请求 alt [动作类型为 continueWith] [动作类型为 intercept] [动作类型为 drop] 客户端 Burp Proxy 扩展插件 目标服务器 User

4. 关键设计意图

  1. 职责分离

    • InterceptedRequest 专注原始请求数据,保持不可变性(需通过 withXxx() 生成新对象)。
    • ProxyRequestReceivedAction 控制请求的初步流向(拦截/放行/丢弃)。
    • ProxyRequestToBeSentAction 提供最终修改机会,确保所有插件修改生效。
  2. 扩展灵活性

    • 允许插件在 不同阶段 介入:
      • 接收阶段:快速决策是否拦截(如基于 URL 黑名单)。
      • 发送阶段:精细化修改(如添加签名头、加密敏感数据)。
  3. 状态一致性

    • 通过分阶段处理,确保修改操作有序(例如先由插件 A 修改头,再由插件 B 加密体)。

值得注意一点,InterceptedRequest的不可变性。InterceptedRequest接口中提供的对其自身的更改,都是产生一个新的HttpRequest类型的对象,将新的对象作为返回值,实际更改才会生效。

Http history tab 中展示的哪一个阶段的HttpRequest对象呢?

  • 传进来的原始请求对象InterceptedRequest
  • handleRequestReceived执行后返回的HttpRequest
  • handleRequestToBeSent执行后返回的HttpRequest

这个其实是可选的。在Settings -> Tools -> Proxy中,如下
在这里插入图片描述


5. 总结

  • InterceptedRequest 是代理拦截的原始请求入口。
  • ProxyRequestReceivedAction 决定请求的初步流向(放行/拦截/丢弃)。
  • ProxyRequestToBeSentAction 控制请求的最终形态,确保修改生效。
  • 协作关系:三者形成代理处理流水线,实现从拦截到发送的全流程控制。

4.3 Demo

通过一个例子,验证前面的知识。不要忘记这张时序图
在这里插入图片描述

package com.mingsec;import burp.api.montoya.BurpExtension;
import burp.api.montoya.EnhancedCapability;
import burp.api.montoya.MontoyaApi;
import burp.api.montoya.core.HighlightColor;
import burp.api.montoya.http.message.requests.HttpRequest;
import burp.api.montoya.proxy.Proxy;
import burp.api.montoya.proxy.ProxyHttpRequestResponse;
import burp.api.montoya.proxy.http.InterceptedRequest;
import burp.api.montoya.proxy.http.ProxyRequestHandler;
import burp.api.montoya.proxy.http.ProxyRequestReceivedAction;
import burp.api.montoya.proxy.http.ProxyRequestToBeSentAction;import java.util.List;
import java.util.Set;public class Ext2025_4 implements BurpExtension {//将MontoyaApi作为静态属性,方便后续传给其他类static MontoyaApi montoya;@Overridepublic void initialize(MontoyaApi api) {//赋值给静态属性Ext2025_4.montoya = api;api.extension().setName("ext2025_4");api.logging().logToOutput("Ext2025_4 by MingSec");//获取Proxy模块的抽象 => Proxy对象Proxy proxy = api.proxy();//判断此时intercept状态boolean interceptEnabled = proxy.isInterceptEnabled();if (interceptEnabled) { //intercept 为 onproxy.disableIntercept();   //设置 intercept 为 offtry {Thread.sleep(7000); //睡眠 7 秒} catch (InterruptedException e) {throw new RuntimeException(e);}}//创建一个实现了ProxyRequestHandler接口的类(在下面)的对象MyProxyRequestHandler myProxyRequestHandler = new MyProxyRequestHandler();proxy.registerRequestHandler(myProxyRequestHandler);    //注册该handlerapi.logging().logToOutput("7秒之期已到,启动!");proxy.enableIntercept();proxy.disableIntercept();//? 获取当前状态下的history,并将requestBody中含password字符串的proxyHttpRequestResponse标注List<ProxyHttpRequestResponse> history = proxy.history();for (ProxyHttpRequestResponse proxyHttpRequestResponse : history) {if (proxyHttpRequestResponse.request().bodyToString().contains("password")) {proxyHttpRequestResponse.annotations().setHighlightColor(HighlightColor.RED);proxyHttpRequestResponse.annotations().setNotes("mingsec");}}}@Overridepublic Set<EnhancedCapability> enhancedCapabilities() {return BurpExtension.super.enhancedCapabilities();}
}//实现 ProxyRequestHandler接口
class MyProxyRequestHandler implements ProxyRequestHandler {MontoyaApi api = Ext2025_4.montoya;String keyword = "password";boolean flag = false;private boolean contains(InterceptedRequest interceptedRequest) {return interceptedRequest.bodyToString().contains(keyword);}@Override/**Proxy代理到流量时调用,返回值ProxyRequestReceivedAction* ProxyRequestReceivedAction 接口中有3个静态方法用于返回一个该类型* - ProxyRequestReceivedAction.intercept(HttpRequest httpRequest) 拦截该请求,等待用户在UI中处理* - ProxyRequestReceivedAction.doNotIntercept(HttpRequest httpRequest) 直接放行* - ProxyRequestReceivedAction.continueWith(HttpRequest httpRequest)   //根据当前规则处理* - ProxyRequestReceivedAction.drop(HttpRequest httpRequest)   丢弃该请求相当于在UI中手动drop*/public ProxyRequestReceivedAction handleRequestReceived(InterceptedRequest interceptedRequest) {this.flag = false;if (interceptedRequest.bodyToString().contains("password")) { //如果代理到的请求体中包含passwordthis.flag = true;//给请求设置高亮和注释interceptedRequest.annotations().setHighlightColor(HighlightColor.BLUE);interceptedRequest.annotations().setNotes("mingsec");//修改请求,返回一个修改后新的请求HttpRequest httpRequest = interceptedRequest.withAddedHeader("author", "mingsec");return ProxyRequestReceivedAction.intercept(httpRequest);   //拦截请求,在UI中展示}return ProxyRequestReceivedAction.doNotIntercept(interceptedRequest);   //将代理到的请求直接放行}@Overridepublic ProxyRequestToBeSentAction handleRequestToBeSent(InterceptedRequest interceptedRequest) {api.logging().logToOutput(hashCode());HttpRequest httpRequest = null;if (flag) {interceptedRequest.annotations().setNotes("mingsec-modified");interceptedRequest.annotations().setHighlightColor(HighlightColor.GREEN);httpRequest = interceptedRequest.withHeader("author", "mingsec by handler");}return ProxyRequestToBeSentAction.continueWith(httpRequest);}
}

5. BurpSuite burpSuite()

在这里插入图片描述


我们看方法细节
在这里插入图片描述
无需传参,只要调用该方法,返回一个BurpSuite类型的对象,BurpSuite接口中声明了许多方法,我们使用该接口的实例化对象调用其中方法,这些方法exposes application-level functionality

6. Extension extension()

在这里插入图片描述
返回一个Extension类型的对象,我们去Extension,如下
在这里插入图片描述
看来看去,好像就这个setName(String extensionName)方法所见即所得,设置扩展名称的代码就如下:

public class HelloBurp implements BurpExtension {// 实现实现该方法@overridevoid initialize(MontoyaApi api) {
/* 加载插件时调用此方法,我们可以在这里写逻辑代码,我们可以写点什么?依靠主程序传入的 MontoyaApi 类型对象,做点什么那么就需要看 MontoyaApi 这个类型提供了什么
*/Extension extension = api.extension();extension.setName("bp扩展");//或者直接写为api.extension().setName("bp扩展");}

7. Http http()

在这里插入图片描述
注意这个方法
在这里插入图片描述

处理即将发送的请求,这是我们最常用的抓包改包功能。调用registerHttpHandler()是注册一个HttpHandler,在这个HttpHandler里面实现我们最想用的功能——改包。我们点进HttpHandler
在这里插入图片描述
这个接口里有两个方法,分别是对发包/请求和和回包/响应进行操作,怎么进行操作呢?这个时候想一下我们改包的具体操作是什么?更改http请求包,更切确地说——更改http请求的文本/字符串。那我们去哪里获取将要发送的http请求包呢?我们先看这两个方法的详情
在这里插入图片描述
调用这个方法需要传入一个HttpRequestToBeSent的实例,看参数说明,这个就是我们需要的http请求包,点进去。

写一个小demo验证我们上面所说的方法。

参考

[1] MontoyaApi
[2] 新版Burpsuite加解密插件开发基础
[3] Burp Extensions: Singletons and Scope
[4] deepseek

http://www.xdnf.cn/news/7875.html

相关文章:

  • 基于stm32的空气质量监测系统
  • 2025年二级等保实施全攻略:传统架构与云等保方案深度解析
  • 乘法逆元:费马小定理(利用快速乘法幂)(JAVA)
  • GitHub 趋势日报 (2025年05月20日)
  • 洛谷B3840 [GESP202306 二级] 找素数
  • MySQL--day5--多表查询
  • 第22天-Python ttkbootstrap 界面美化指南
  • 漏洞扫描企业如何助力企业预防安全风险应对网络攻击?
  • GUI实验
  • vue3 threejs 物体发光描边
  • Python人工智能算法 模拟退火算法:原理、实现与应用
  • 项目执行中缺乏问题记录和总结,如何改进?
  • [java]数组
  • 7.数据的预测分析及可视化
  • 嵌入式STM32学习——串口USART 2.0(printf重定义及串口发送)
  • Word2Vec模型学习和Word2Vec提取相似文本体验
  • 豪越智能仓储:为消防应急物资管理“上锁”
  • Nginx 强制 HTTPS:提升网站安全性的关键一步
  • Arthas:Java诊断利器实战指南
  • 游戏服务器开发:如何实现客户端与服务端通信
  • 【Unity 如何使用 Mixamo下载免费模型/动画资源】Mixamo 结合在 Unity 中的实现(Animtor动画系统,完整配置以及效果展示)
  • 如何通过小贝加速实现精准网络故障排查
  • 使用 Shadcn UI 构建 Java 桌面应用
  • 六:操作系统虚拟内存之缺页中断
  • PHP:经典编程语言在当代Web开发中的新活力
  • YOLOv4深度解析:从架构创新到工业落地的目标检测里程碑
  • git工具使用
  • 【VxWorks 实时操作系统(RTOS)】常用函数汇总
  • 期刊采编系统安装升级错误
  • 25_05_19Linux实战篇、第一章_01若依前后端部署之路(后端)