【BurpSuite 2025最新版插件开发】基础篇7:数据的持久化存储

1 前言

历史章节:

【BurpSuite 2025最新版插件开发】基础篇1:环境搭建

【BurpSuite 2025最新版插件开发】基础篇2:插件生命周期与核心接口

【BurpSuite 2025最新版插件开发】基础篇3:请求拦截和修改简单示例

【BurpSuite 2025最新版插件开发】基础篇4:HTTP流量处理

【BurpSuite 2025最新版插件开发】基础篇5:UI组件开发

【BurpSuite 2025最新版插件开发】基础篇6:UI组件与数据传输

本章节注意讲解 BurpSuite 插件中对于数据持久化存储的基本使用。

2 接口简介

BurpSuite 官方接口
在这里插入图片描述

2.1 PersistedList<T>:项目级列表存储

  • 功能定位
    存储有序的、可重复的数据列表,支持泛型类型(如字符串、整数等),数据随Burp项目文件保存。
  • 核心特性
    • 类型安全:通过泛型约束元素类型(如PersistedList<String>)。
    • 项目隔离:每个项目独立保存列表数据,切换项目时自动加载对应数据。
    • 动态操作:支持addremovesize等列表操作,适合存储可变数据集合(如URL历史记录)。
  • 使用场景
    存储插件运行时动态生成的列表数据(如扫描结果、自定义Payload列表)。

2.2 PersistedObject:项目级复杂对象存储(仅供专业版)

  • 功能定位
    存储单个结构化对象(如配置类、自定义数据模型),需实现java.io.Serializable接口。
  • 核心特性
    • 复杂数据支持:可存储嵌套对象、集合等复杂结构。
    • 项目绑定:数据与项目关联,适合保存项目特定的配置或状态。
    • 版本兼容性:需注意序列化版本UID,避免跨版本兼容性问题。
  • 使用场景
    存储插件的完整配置(如多模块扫描策略)或复杂状态数据。

2.3 Persistence:持久化功能入口

  • 功能定位
    工厂接口,用于创建和管理PersistedListPersistedObject实例。
  • 核心方法
    • createPersistedList(String name, Class<T> elementType):创建命名列表。
    • persistedObject(String name):获取或创建命名对象。
  • 使用场景
    插件初始化时通过montoya.persistence()获取实例,再创建具体持久化存储。

2.4 Preferences:用户级全局配置

  • 功能定位
    存储与项目无关的用户偏好或全局设置(如API密钥、界面主题)。
  • 核心特性
    • 跨项目共享:数据存储在用户配置文件中,所有项目均可访问。
    • 基本类型支持:仅支持字符串、布尔值、整数等简单类型。
    • 监听机制:可注册监听器实时响应配置变化。
  • 使用场景
    存储插件的全局设置(如默认扫描选项、认证凭证)。

2.5 持久化接口对比与选择建议

接口名称PersistedListPersistedObjectPersistencePreferences
功能定位存储有序、可重复的数据列表,支持泛型类型。存储单个结构化对象(如配置类、数据模型)。工厂接口,用于创建和管理其他持久化接口。存储用户级全局配置(与项目无关)。
数据作用域项目级(随项目文件保存)。项目级(随项目文件保存)。-用户级(跨项目共享)。
支持数据类型泛型列表(需指定元素类型)。内置类型(如HTTP请求/响应)、自定义对象。-基本类型(String、Boolean、Integer等)。
序列化要求元素需实现 Serializable(如自定义类)。文档未明确要求,但自定义对象可能需适配。-无需序列化。
核心方法add, remove, get, size, clearset, get, setChildObject, removecreatePersistedList, persistedObjectput, get, remove, addListener
典型场景存储动态生成的项目相关列表(如URL历史)。存储复杂配置或项目状态(如多模块策略)。插件初始化时获取持久化功能入口。存储全局用户偏好(如API密钥、主题)。
版本限制社区版/专业版均可使用。专业版(标注 [Professional only])。社区版/专业版均可使用。社区版/专业版均可使用。

关键说明

  1. PersistedList 适合动态增删的列表场景,但查询效率依赖列表长度(O(n))。
  2. PersistedObject 支持复杂数据结构,但需注意专业版限制及可能的序列化适配。
  3. Persistence 是创建其他持久化对象的唯一入口,需通过 montoya.persistence() 获取。
  4. Preferences 适合存储与项目无关的配置,数据跨项目共享且无需序列化。

3 实战模拟

插件实现如下需求:

  • 通过 HTTP 接口获取不同类型用户的信息:token、uid、role 后进行持久化存储。
  • 在业务接口中使用不同类型用户的信息调用业务接口,来测试业务接口的权限隔离。
  • 使用 BurpSuite 版本通用PersistedList 接口实现数据持久化。

4 代码示例

4.1 服务端代码

使用 python 代码实现极简服务端,实现如下需求:

  • 预先定义了系统固定的用户和管理员信息,包含 token、uid 和 role 三个字段。
  • 实现 3 个接口:
  1. 获取用户信息接口(/user_info)

    • 请求方法:GET
    • 功能:返回预先定义的用户信息,包含 token、uid 和 role。
    • 响应示例:
      在这里插入图片描述
  2. 获取管理员信息接口(/admin_info)

    • 请求方法:GET
    • 功能:返回预先定义的管理员信息,包含 token、uid 和 role。
    • 响应示例:在这里插入图片描述
  3. 添加用户接口(/add_user)

    • 请求方法:POST

    • 请求参数:以 JSON 格式传递 token、uid 和 role 三个参数。

    • 功能:检查传入的参数是否与预先定义的管理员信息一致,若一致则返回添加成功的消息;若不一致则返回添加失败的消息。

    • 成功响应示例:在这里插入图片描述

    • 失败响应示例:
      在这里插入图片描述

服务端 python 代码:

from flask import Flask, request, jsonifyapp = Flask(__name__)# 模拟用户和管理员信息
USER_INFO = {"token": "user_token_123","uid": "user_uid_123","role": "user"
}ADMIN_INFO = {"token": "admin_token_123","uid": "admin_uid_123","role": "admin"
}# 获取用户信息接口
@app.route('/user_info', methods=['GET'])
def get_user_info():return jsonify(USER_INFO)# 获取管理员信息接口
@app.route('/admin_info', methods=['GET'])
def get_admin_info():return jsonify(ADMIN_INFO)# 添加用户接口
@app.route('/add_user', methods=['POST'])
def add_user():data = request.get_json()if not data or 'token' not in data or 'uid' not in data or 'role' not in data:return jsonify({"message": "Missing parameters"}), 400if data['token'] == ADMIN_INFO['token'] and data['uid'] == ADMIN_INFO['uid'] and data['role'] == ADMIN_INFO['role']:return jsonify({"message": "User added successfully"}), 200else:return jsonify({"message": "Adding user failed"}), 400if __name__ == '__main__':app.run(debug=True)

通过命令行启动:
在这里插入图片描述

4.2 插件代码

实现需求:

  • 拦截 HTTP 响应、持久化存储用户数据。
  • 通过右键菜单触发的业务接口的测试请求。
  • 测试请求分别使用 user 和 admin 的信息请求 /add_user 接口。
  1. Extension.java
    • 插件的主类,实现了 BurpExtension 接口,设置插件名称。
    • 创建两个 PersistedList<String> 实例,用于持久化存储用户信息和管理员信息。
    • 注册 CustomHttpHandler 来处理 HTTP 请求/响应。
    • 注册 TestMenu 右键菜单项。
import burp.api.montoya.BurpExtension;
import burp.api.montoya.MontoyaApi;
import burp.api.montoya.persistence.PersistedList;@SuppressWarnings("unused")
public class Extension implements BurpExtension {@Overridepublic void initialize(MontoyaApi montoyaApi) {montoyaApi.extension().setName("My Extension");// 创建持久化对象PersistedList<String> userInfoList = PersistedList.persistedStringList();PersistedList<String> adminInfoList = PersistedList.persistedStringList();// HTTP 监听器montoyaApi.http().registerHttpHandler(new CustomHttpHandler(montoyaApi, userInfoList, adminInfoList));// 注册右键-测试请求montoyaApi.userInterface().registerContextMenuItemsProvider(new TestMenu(montoyaApi, userInfoList, adminInfoList));}
}
  1. CustomHttpHandler.java
    • 该类实现了 HttpHandler 接口,用于监听和处理 HTTP 请求与响应。
    • handleHttpResponseReceived 方法中,检查响应内容是否包含 "role": "user""role": "admin",并分别将这些信息添加到 userInfoListadminInfoList 中。
import burp.api.montoya.MontoyaApi;
import burp.api.montoya.http.handler.*;
import burp.api.montoya.persistence.PersistedList;public class CustomHttpHandler implements HttpHandler {private final MontoyaApi montoyaApi;private final PersistedList<String> userInfoList;private final PersistedList<String> adminInfoList;public CustomHttpHandler(MontoyaApi montoyaApi, PersistedList<String> userInfoList, PersistedList<String> adminInfoList) {this.montoyaApi = montoyaApi;this.userInfoList = userInfoList;this.adminInfoList = adminInfoList;}@Overridepublic RequestToBeSentAction handleHttpRequestToBeSent(HttpRequestToBeSent httpRequestToBeSent) {return RequestToBeSentAction.continueWith(httpRequestToBeSent);}@Overridepublic ResponseReceivedAction handleHttpResponseReceived(HttpResponseReceived httpResponseReceived) {// 持久化存储if (httpResponseReceived.bodyToString().contains("\"role\": \"user\"")) {userInfoList.add(httpResponseReceived.body().toString());String userValue = userInfoList.stream().findFirst().orElse("无用户信息");montoyaApi.logging().logToOutput("获取 UserInfoList: " + userValue);}if (httpResponseReceived.bodyToString().contains("\"role\": \"admin\"")) {adminInfoList.add(httpResponseReceived.body().toString());String adminValue = adminInfoList.stream().findFirst().orElse("无管理员信息");montoyaApi.logging().logToOutput("获取 AdminInfoList: " + adminValue);}// 打印响应montoyaApi.logging().logToOutput("响应体: " + httpResponseReceived.bodyToString());return ResponseReceivedAction.continueWith(httpResponseReceived);}
}
  1. TestMenu.java
    • 该类实现了 ContextMenuItemsProvider 接口,为 Burp 的上下文菜单提供自定义菜单项。
    • 提供一个名为“测试请求”的菜单项;点击菜单项后会调用 MyRequest.sendTestRequest(...) 方法,传递 userInfoListadminInfoList
    • 使用事件监听机制来触发请求。
import burp.api.montoya.MontoyaApi;
import burp.api.montoya.persistence.PersistedList;
import burp.api.montoya.ui.contextmenu.ContextMenuEvent;
import burp.api.montoya.ui.contextmenu.ContextMenuItemsProvider;import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;public class TestMenu implements ContextMenuItemsProvider {private final MontoyaApi montoyaApi;private final PersistedList<String> userInfoList;private final PersistedList<String> adminInfoList;public TestMenu(MontoyaApi montoyaApi, PersistedList<String> userInfoList, PersistedList<String> adminInfoList) {this.montoyaApi = montoyaApi;this.userInfoList = userInfoList;this.adminInfoList = adminInfoList;}@Overridepublic List<Component> provideMenuItems(ContextMenuEvent event) {List<Component> menuItems = new ArrayList<>();JMenuItem menuItem = new JMenuItem("测试请求");menuItem.addActionListener(e -> {MyRequest myRequest = new MyRequest(montoyaApi);myRequest.sendTestRequest(userInfoList, adminInfoList);});menuItems.add(menuItem);return menuItems;}
}
  1. MyRequest.java
    • 该类封装了发送 HTTP 请求的逻辑。
    • sendTestRequest(...) 方法从 PersistedList<String> 中提取第一个用户信息和管理员信息;如果信息为空,则记录错误日志;
    • 使用 SwingWorker 异步执行网络操作,避免阻塞主线程;
    • sendRequest(...) 方法解析 JSON 数据,并构造新的 HTTP POST 请求发送到服务器。
import burp.api.montoya.MontoyaApi;
import burp.api.montoya.http.HttpService;
import burp.api.montoya.http.message.requests.HttpRequest;
import burp.api.montoya.persistence.PersistedList;
import burp.api.montoya.utilities.json.JsonUtils;import javax.swing.*;public class MyRequest {private final MontoyaApi montoyaApi;public MyRequest(MontoyaApi montoyaApi) {this.montoyaApi = montoyaApi;}public void sendTestRequest(PersistedList<String> userInfoList, PersistedList<String> adminInfoList) {String userValue = userInfoList.stream().findFirst().orElse("");String adminValue = adminInfoList.stream().findFirst().orElse("");if (userValue.isEmpty() || adminValue.isEmpty()) {montoyaApi.logging().logToError("no user info or admin info");return;}new SwingWorker<Void, Void>() {@Overrideprotected Void doInBackground() {sendRequest(userInfoList, "user");sendRequest(adminInfoList, "admin");return null;}}.execute();}private void sendRequest(PersistedList<String> dataList, String roleType) {try {String infoValue = dataList.stream().findFirst().orElse(null);if (infoValue == null) {montoyaApi.logging().logToError("数据为空: " + roleType);return;}JsonUtils jsonUtils = montoyaApi.utilities().jsonUtils();String role = jsonUtils.readString(infoValue, "role");String token = jsonUtils.readString(infoValue, "token");String uid = jsonUtils.readString(infoValue, "uid");String requestBody = String.format("{\"role\":\"%s\",\"token\":\"%s\",\"uid\":\"%s\"}", role, token, uid);HttpService httpService = HttpService.httpService("localhost", 5000, false);HttpRequest httpRequest = HttpRequest.httpRequest().withPath("/add_user").withService(httpService).withBody(requestBody).withHeader("Content-Type", "application/json").withMethod("POST");montoyaApi.http().sendRequest(httpRequest);} catch (Exception e) {montoyaApi.logging().logToError("error:" + e.getMessage());}}
}

5 效果展示

5.1 抓包接口获取用户数据

获取 user 信息:
在这里插入图片描述
获取 admin 信息:
在这里插入图片描述
日志打印:
在这里插入图片描述

5.2 右键触发测试请求

触发请求 /add_user 接口:
在这里插入图片描述
日志打印:可以看到输出日志符合服务端的判断。

插件:

sendRequest(userInfoList, "user");
sendRequest(adminInfoList, "admin");

服务端:

if data['token'] == ADMIN_INFO['token'] and data['uid'] == ADMIN_INFO['uid'] and data['role'] == ADMIN_INFO['role']:return jsonify({"message": "User added successfully"}), 200else:return jsonify({"message": "Adding user failed"}), 400

在这里插入图片描述

6 总结

  • 整个插件的功能流程如下:

    1. 拦截响应:通过 CustomHttpHandler 类拦截 HTTP 响应,识别包含 "role": "user""role": "admin"的响应体,并将其持久化存储到 PersistedList 中;
    2. 持久化存储:使用 Montoya API 的 PersistedList 来保存用户和管理员信息;
    3. 触发测试请求:通过右键菜单项(由 TestMenu 类实现)触发测试请求;
    4. 异步发送请求:在后台线程中使用 MyRequest 类发送包含用户和管理员信息的 HTTP 请求,避免阻塞 UI。
  • 本插件适用于需要从响应中提取特定信息基于这些信息发起新请求的安全测试场景。

:由于社区版不支持保存项目到本地,因此要最大程度的发挥persistence的作用建议使用专业版

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/87307.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/87307.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GPT-4 Turbo集成智能工作流,开启自动化研究与知识管理新篇章!

目录 一、系统架构设计二、核心模块实现1. 智能数据采集引擎2. 自动化研究引擎3. 知识管理系统 三、智能工作流引擎四、关键技术实现1. 动态工作流引擎2. 知识图谱构建 五、企业级部署方案1. 云原生架构2. Docker部署脚本 六、应用案例&#xff1a;药物研发项目七、性能优化策略…

告别SQL卡顿与混乱!AI如何赋能实时计算?

在当今数据驱动的商业环境中&#xff0c;SQL作为与数据库交互的核心语言&#xff0c;其编写效率和质量直接影响着企业的数据决策速度和系统性能。然而&#xff0c;我们在长期的企业服务实践中发现&#xff0c;数据库开发人员普遍面临以下痛点&#xff1a; SQL性能问题频发&…

LeetCode算法(和中等打的有来有回)——盛最多水的容器

文章目录 leetcode第11题&#xff1a;盛最多水的容器二次循环代码 双指针优化解析代码 leetcode第11题&#xff1a;盛最多水的容器 二次循环 这道题比较容易想到的就是通过二次循环遍历所有能盛的水的体积。 代码 class Solution {public int maxArea(int[] height) {// 记录…

Karmada 多集群服务发现

一、背景介绍 多集群架构下&#xff0c;不同 Kubernetes 集群间的服务如何互通是核心挑战。Karmada 支持 Kubernetes Multi‑cluster Service APIs&#xff08;MCS&#xff09;&#xff0c;通过 ServiceExport 和 ServiceImport 实现跨集群服务发现与调用&#xff0c;帮助多集…

macOS 26正式发布,全新Liquid Glass设计语言亮相

在全球科技爱好者翘首以盼的WWDC 2025开发者大会上&#xff0c;苹果公司正式揭开了macOS 26系统的神秘面纱。此次系统更新最令人瞩目的&#xff0c;当属其采用的全新Liquid Glass设计语言&#xff0c;该设计不仅重塑了Mac的视觉风格&#xff0c;更为用户带来了一场前所未有的操…

网络基础(3)

网络基础&#xff08;3&#xff09; 有关进程 1&#xff09;进程是人在系统中的代表&#xff0c;只要把数据给进程&#xff0c;人就相当于拿到了数据 2&#xff09;数据传输到主机不是目的&#xff0c;而是手段。到达主机内部&#xff0c;再交给主机内的进程才是目的 上网的…

C语言专题:17.逻辑运算与三目运算符(按位逻辑运算、条件运算符)

​ C语言中的逻辑运算符和三目运算符&#xff08;条件运算符&#xff09;是非常常见且基础的操作符&#xff0c;它们分别用于布尔逻辑运算和简化条件判断的表达式。通过合理使用这些运算符&#xff0c;可以使代码更加简洁、清晰。本文将重点介绍逻辑运算符、三目运算符和按位逻…

【分布式 ID】一文详解美团 Leaf

文章目录 1. 前言2. 项目启动示例 - MYSQL 和 Zookeepr2.1 Leaf-segment 模式2.2 Leaf-snowflake 模式 - 单节点2.3 Leaf-snowflake 模式 - 多节点 3. Leaf-segment 详细讲解4. Leaf-segment 源码解析4.1 SegmentBuffer 号段缓存4.2 Segment 号段4.3 初始化号段服务 SegmentIDG…

互联网大厂Java面试实录:Spring Boot与微服务在电商场景中的应用

互联网大厂Java面试实录&#xff1a;Spring Boot与微服务在电商场景中的应用 面试场景 面试官&#xff1a;你好&#xff0c;谢飞机&#xff0c;欢迎参加我们的Java开发岗位面试。首先&#xff0c;能否简单介绍一下你的技术背景&#xff1f; 谢飞机&#xff1a;嗨&#xff0c…

XILINX Ultrascale+ Kintex系列FPGA的架构

Xilinx&#xff08;现为AMD&#xff09;Kintex UltraScale系列FPGA是基于16nm FinFET工艺的高性能、中等成本的现场可编程门阵列&#xff0c;专为高带宽、低功耗和成本效益的应用设计&#xff0c;广泛用于5G通信、数据中心、视频处理、航空航天等领域。以下详细介绍Kintex Ultr…

腾讯云实名资质 “待补充后提交” 解决方法

目录 一、引言二、为什么会出现 “待补充后提交” 状态三、需要补充的具体材料3.1 营业执照3.2 法人身份证相关3.3 短信管理员资料3.4 合规使用承诺函 四、处理流程详细步骤4.1 登录腾讯云控制台4.2 进入实名资质相关页面4.3 上传补充材料4.4 提交审核 五、注意事项5.1 材料规范…

8分钟讲完 Tomcat架构及工作原理

https://www.bilibili.com/video/BV1J3411k7Xc/?spm_id_from333.337.search-card.all.click&vd_source36145f3620bdf21c0f1a843352e603fb JavaWeb开发必看&#xff01;Tomcat架构及工作原理&#xff08;8分钟&#xff09; 分阐明了Tomcat的工作原理。 一、Tomcat的核心架…

C盘爆满元凶!WinSxS组件解密

C盘爆满元凶!WinSxS组件解密 WinSxS是什么?核心功能与重要性目录为何疯狂膨胀?安全清理权威指南优先使用微软官方工具:DISM工具清理效果与性能影响重要风险提示总结C盘爆满元凶!WinSxS组件解密你是否也遇到过: C盘空间频频告急,检查发现WinSxS文件夹竟独占数十GB空间?想…

毕业设计(启智模块化机器人的组装与K5的使用

记录一下 毕业设计的部分笔记 准备清空文件发到csdn做一个纪念0.0 物联网毕业设计 机器的组装与K5的使用 基础文件的学习 首先安装K5 和文件包中的JLink驱动 并且文件实例里的代码必须加上x后缀否则 只能用K4 来打开 供电&#xff1a;整个系统都需要电池运转 build 存放…

从0开始学习R语言--Day37--CMH检验

对于有多个特征的数据&#xff0c;我们一般的处理方式是构建特征函数&#xff0c;计算每个特征向量的系数&#xff0c;从而将其影响纳入到研究量中&#xff0c;但对于简单的问题&#xff0c;也这样做的话未免有点小题大做。这时我们可以考虑用CMH来分析变量在每个特征下的影响&…

搜索选择DFS还是BFS

1. DFS&#xff08;深度优先搜索&#xff09;&#xff1a;优先进行深度纵向搜索&#xff0c;DFS所需的内存少于BFS所需的内存&#xff0c;利用堆栈实现&#xff0c;适合找最短路径。 2. BFS&#xff08;广度优先搜索&#xff09;&#xff1a;优先进行广度横向搜索&#xff0c;…

三格电子——电力协议转换器

Modbus 转 IE104 网关型号 SG-TCP-IEC104 &#xff0c;是三格电子推出的工业级网关&#xff08;以下简称网 关&#xff09;&#xff0c;主要用于 Modbus RTU/TCP/ASCII 数据采集、 DLT645-1997/2007 数据采集&#xff0c;可接多功 能电力仪表、温控仪、电表等&#xf…

UE5 瞄准偏移(AimOffset)功能详解

什么是AimOffset? AimOffset(瞄准偏移)是一种特殊的动画混合空间(类似于 Blend Space),它通过将多个预设姿势叠加到一个基础动作上,实现角色根据视角方向进行上下左右的动画混合。简单来说,AimOffset 在射击游戏中常用来处理角色持枪瞄准时的动作,比如抬头、低头、左…

在Ubuntu24上安装ollama

安装ollama之前&#xff0c;建议检查显卡驱动是否安装完成。如果还未安装显卡驱动&#xff0c;建议先安装显卡驱动再安装ollama。 安装curl sudo apt update sudo apt -y install curl进入ollama的下载网站 https://ollama.com/download/linux 复制安装脚本&#xff0c;并在…

【Kafka使用方式以及原理】

Kafka生产者发送消息的方式 Kafka生产者发送消息主要通过以下三种方式&#xff1a; 同步发送 生产者发送消息后&#xff0c;会阻塞等待Broker的响应&#xff0c;确认消息是否成功写入。这种方式可靠性高&#xff0c;但吞吐量较低。代码示例&#xff1a; ProducerRecord<S…