Burp Suite Extension Development Guide

Burp Suite是什么?

Burp Suite是一款Web应用程序渗透测试工具,可以帮助用户发现和利用Web应用程序中的漏洞,提高渗透测试的效率和精度。

Web应用程序最常用的传输数据的协议就是HTTP/HTTPS,所以我们将从HTTP协议的数据格式开始介绍。

HTTP/HTTPS协议内容简要划分

Burp中最为核心的对象就是HTTP数据包,我们的所有操作、各种API接口都是围绕HTTP数据包展开的。下图对HTTP数据包进行划分:
Burp Suite Extension Development Guide

数据映射表:
Burp Suite Extension Development Guide

插件能对HTTP数据包做的操作无非“增删查改”四种,下面这段代码对常用操作均进行了演示。
https://github.com/bit4woo/burp-api-drops/blob/master/src/burp/Lession5.java

请求包:

  • header获取删除新增修改

  • body获取修改

  • parameter获取删除新增修改

  • 发送一个新的请求

响应包:

  • header获取删除新增修改

  • body获取修改

httpService:

  • host获取修改
  • port获取修改
  • protocol获取修改

插件的调用原理介绍

以下全文将以Java语言的视角展开,
Burp Suite Extension Development Guide

  1. 插件的总入口是BurpExtender类,该类是必须得实现IBurpExtender接口;

  2. 当实现IBurpExtender接口后,会要求重写registerExtenderCallbacks()方法,而该函数的作用就是注册回调,当自己的写的插件需要哪些API支持的时候,都需要在该函数中进行注册,这样burp在执行的时候,会读取自己写的插件代码是否有回调注册,如果有就进行执行相应代码。

基本逻辑流程如下:
BurpExtender类————> registerExtenderCallbacks()方法 ————> 调用Callbacks.registerXxx接口名称(this) ————> 去执行注册接口的方法

Burp Suite的API的简要划分

Burp Suite 提供了丰富的插件接口,可以让开发者编写自定义插件,扩展 Burp Suite 的功能。 最新版本的APIs还是挺多的,想要高效的编写出插件,还是得了解你的需求,根据需求去匹配使用相关接口,下面我列举一些常用的 Burp Suite 插件接口类:

  • IBurpExtender 接口:该接口用于定义 Burp Suite 插件的入口点,即插件的主类。在该接口的 registerExtenderCallbacks 方法中,开发者可以注册其他插件接口类和事件监听器。

  • IExtensionStateListener 接口:该接口用于定义插件状态的变化监听器。开发者可以通过实现该接口,监视插件的启动、停止和卸载等事件,并在这些事件发生时执行自定义的操作。

  • IHttpListener 接口:该接口用于定义 HTTP 拦截器。通过实现该接口,开发者可以在 Burp Suite 中拦截 HTTP 请求和响应,并实现自定义的处理逻辑,例如修改请求或响应、分析参数等。

  • IScannerCheck 接口:该接口用于定义漏洞扫描器。通过实现该接口,开发者可以编写自定义的漏洞检测逻辑,并将其集成到 Burp Suite 的漏洞扫描器中,从而提高漏洞检测的效率和精度。

  • IIntruderPayloadGenerator 接口:该接口用于定义 Intruder 负载生成器。通过实现该接口,开发者可以编写自定义的负载生成逻辑,并将其集成到 Burp Suite 的 Intruder 工具中,用于进行爆破和暴力破解等攻击。

  • IContextMenuFactory 接口:该接口用于定义右键菜单工厂。通过实现该接口,开发者可以向 Burp Suite 的右键菜单中添加自定义的菜单项,并实现菜单项的点击事件。

  • IMessageEditorTabFactory 接口:该接口用于定义消息编辑器选项卡工厂。通过实现该接口,开发者可以向 Burp Suite 的消息编辑器中添加自定义的选项卡,并实现选项卡的内容显示和编辑功能。

开发流程简介

大体步骤如下:
Burp Suite Extension Development Guide

  • 创建项目、导入jar包
    开发插件有些规定需要记住,目录名必须设置成burp目录,类名即文件名必须是BurpExtender。
    导入burp的接口jar包有多种方式,我下面以maven的方式举例:
<dependencies>     <!-- https://mvnrepository.com/artifact/net.portswigger.burp.extender/burp-extender-api -->     <dependency>         <groupId>net.portswigger.burp.extender</groupId>         <artifactId>burp-extender-api</artifactId>         <version>1.7.22</version>     </dependency> </dependencies> 
  • 开发功能模块
  • 编译打包
<build>     <plugins>         <plugin>             <groupId>org.apache.maven.plugins</groupId>             <artifactId>maven-assembly-plugin</artifactId>             <executions>                 <execution>                     <phase>package</phase>                     <goals>                         <goal>single</goal>                     </goals>                 </execution>             </executions>             <configuration>                 <descriptorRefs>                     <descriptorRef>jar-with-dependencies</descriptorRef>                 </descriptorRefs>             </configuration>         </plugin>     </plugins> </build> 

打开终端,输入打包jar包命令:

mvn clean install 
  • Burp Suite导入刚编译好的jar包进行测试、使用。

案例1 —— 对HTTPHTTPS数据流处理

如果想要实现对HTTPHTTPS数据的操作,那么就需要了解IHttpListener接口中的processHttpMessage方法

Burp的IHttpListener接口用于扩展Burp Suite的HTTP拦截器,通过实现该接口可以在HTTP请求和响应被拦截时执行一些自定义的操作。

IHttpListener接口中的processHttpMessage方法用于处理拦截到的HTTP请求和响应,其方法签名如下:

void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo); 

其中:

  • toolFlag 参数表示触发拦截的工具,可以是 Burp Suite 中的 Proxy、Scanner、Spider 等工具;
  • messageIsRequest 参数表示拦截到的消息是请求还是响应;
    • 当 messageIsRequest 参数为 true 时,表示拦截的是请求内容
    • 当 messageIsRequest 参数为 false 时,表示拦截的是响应内容
  • messageInfo 参数表示拦截到的HTTP请求/响应的详细信息,包括请求/响应头、请求/响应体、请求/响应的地址、协议版本等等。

在实现IHttpListener接口时,通常会在processHttpMessage方法中编写自定义的处理逻辑,比如对请求/响应进行修改、分析请求/响应的参数等,从而实现自定义的HTTP拦截功能。

总之,通过实现IHttpListener接口,并在其中实现processHttpMessage方法,可以为Burp Suite的HTTP拦截器添加自定义的处理逻辑,从而提高渗透测试的效率和精度。

下面主要讲解一个通过对HTTPHTTPS数据流的拦截、处理,在head添加 X-forwarded-for 一个请求头,伪造客户端IP测试的案例。

可以配合在线工具,进行测试:
https://uutool.cn/mock/
主要用来模拟服务端收到请求后,查看请求内容。
Burp Suite Extension Development Guide

code:

package burp;  import burp.IBurpExtender; import burp.IBurpExtenderCallbacks; import burp.IExtensionHelpers;  import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.List;  public class BurpExtender implements IBurpExtender, IHttpListener, IExtensionStateListener {     private IExtensionHelpers helpers;     private IBurpExtenderCallbacks callbacks;     private PrintWriter stdout;     private PrintWriter stderr;      @Override     public void registerExtenderCallbacks(IBurpExtenderCallbacks iBurpExtenderCallbacks) {         this.callbacks = iBurpExtenderCallbacks;         //设置插件名字         callbacks.setExtensionName("Demo1");         this.helpers = callbacks.getHelpers();          // 一定要注册监听器,不然下面的函数无法生效         callbacks.registerHttpListener(this);         callbacks.registerExtensionStateListener(this);          this.stdout = new PrintWriter(callbacks.getStdout(), true);         this.stderr = new PrintWriter(callbacks.getStderr(), true);          // 打印信息在UI控制台页面 Output and Errors         stdout.println("Hello Demo1 Extender !");         stderr.println("Error Info Show.");     }       @Override     public void processHttpMessage(int i, boolean b, IHttpRequestResponse iHttpRequestResponse) {         //设置http监听模块为Burpsuiteproxy模块         if (i == IBurpExtenderCallbacks.TOOL_PROXY) {              if (b) { //对请求包进行处理                  //获取协议 端口 和主机名                 IHttpService service = iHttpRequestResponse.getHttpService();                 stdout.println("=============***============= Protocol host port :" + service.getProtocol() + " " + service.getHost() + " " + service.getPort());                  //对消息体进行解析,messageInfo是整个HTTP请求和响应消息体的总和,各种HTTP相关信息的获取都来自于它,HTTP流量的修改都是围绕它进行的。                 IRequestInfo analyzeRequest = helpers.analyzeRequest(iHttpRequestResponse);                  // 获取参数                 List<IParameter> parameList = analyzeRequest.getParameters();                 //获取参数 、遍历参数                 for (IParameter para : parameList) {                     //获取参数                     String key = para.getName();                     //获取参数值(value)                     String value = para.getValue();                     int type = para.getType();                     stdout.println("parameters key value type :" + key + " " + value + " " + type);                 }                  // 更新拦截处理后的数据  +                 IRequestInfo analyIRequestInfo = helpers.analyzeRequest(iHttpRequestResponse);                 //获取整个请求数据内容                 String request = null;                 try {                     request = new String(iHttpRequestResponse.getRequest(), "UTF-8");                 } catch (UnsupportedEncodingException e) {                     throw new RuntimeException(e);                 }                  //通过上面的analyIRequestInfo得到请求数据包体(body)的起始偏移                 int bodyOffset = analyIRequestInfo.getBodyOffset();                  //通过起始偏移点得到请求数据包体(body)的内容                 byte[] body = null;                 try {                     body = request.substring(bodyOffset).getBytes("UTF-8");                 } catch (UnsupportedEncodingException e) {                     throw new RuntimeException(e);                 }                  //通过上面的analyIRequestInfo得到请求数据的请求头列表                 List<String> headers = analyIRequestInfo.getHeaders();//获取http请求头的信息                  //生成X-Forwarded-For请求头 包括请求头的key(X-Forwarded-For)及随机生成的IP                 String xForwardFor = "X-Forwarded-For: " + RandomIP.getRandomIP();                  //新增header头, 添加x-forwarded-for请求头,伪造客户端IP测试                 headers.add(xForwardFor);                 headers.add("Test-Head: I am a test data!!!");                  //遍历请求头                 for (String header : headers) {                     stdout.println("header : " + header);                 }                  //重新构造了请求数据                 byte[] newRequest = helpers.buildHttpMessage(headers, body);                  //打印出重新构造的请求数据测试                 stdout.println(helpers.analyzeRequest(newRequest).getHeaders());                  //重新构造的新请求数据, 因为里面已经包含有我们添加的X-Forward-For                 iHttpRequestResponse.setRequest(newRequest);              } else {//对响应包进行处理                 // Response                 IResponseInfo analyzeResponse = helpers.analyzeResponse(iHttpRequestResponse.getResponse());                 //获取响应码信息                 short statusCode = analyzeResponse.getStatusCode();                 stdout.println("status= " + statusCode);                  //获取响应头信息                 List<String> headers = analyzeResponse.getHeaders();                 for (String header : headers) {                     stdout.println("header:" + header);                 }                  // 获取响应信息                 String resp = new String(iHttpRequestResponse.getResponse());                 int bodyOffset = analyzeResponse.getBodyOffset();                 String body = resp.substring(bodyOffset);                 stdout.println("response body=" + body);             }         }     }      // 用于注册插件状态监听,在卸载插件时会执行     public void extensionUnloaded() {         String fileName = "D:\testData\example.txt";         String fileContent = "The Demo1 extension removed!";          try {             FileWriter fileWriter = new FileWriter(fileName);             fileWriter.write(fileContent);             fileWriter.close();             System.out.println("Successfully wrote to the file.");         } catch (IOException e) {             System.out.println("An error occurred.");             e.printStackTrace();         }     } } 

案例2 —— 高亮、新标签界面

高亮非常简单:

iHttpRequestResponse.setHighlight("red"); iHttpRequestResponse.setHighlight("yellow"); iHttpRequestResponse.setHighlight("blue"); // ... 

新标签界面:
如果想要实现在请求和响应界面加一个新标签页来展示自定义信息,那么就需要了解IMessageEditorTab接口setMessage方法
Burp的IMessageEditorTab接口是用于扩展 Burp Suite 的请求/响应编辑器的一种方式,通过实现该接口可以向编辑器中添加自定义的标签页,实现自定义的请求/响应内容编辑功能。

IMessageEditorTab 接口中的setMessage方法用于设置当前编辑器中显示的请求/响应内容。该方法的签名如下:

void setMessage(byte[] message, boolean isRequest); 

其中:

  • message 参数表示要设置的请求/响应内容的字节数组;
  • isRequest 参数表示设置的内容是请求还是响应,
    • 当 isRequest 参数为 true 时,表示设置的是请求内容
    • 当 isRequest 参数为 false 时,表示设置的是响应内容

在实现 IMessageEditorTab 接口时,通常会在自定义的标签页中添加一个编辑器组件(如 TextArea),并在 setMessage 方法中将请求/响应内容设置到该组件中,从而在标签页中显示请求/响应内容。同时,还可以在自定义的标签页中添加一些其他的组件,比如按钮、复选框等,实现一些自定义的功能,如发送请求、解析响应等。

总之,通过实现 IMessageEditorTab 接口,并在其中实现 setMessage 方法,可以为 Burp Suite 的请求/响应编辑器添加自定义的标签页及编辑功能,从而提高渗透测试的效率和精度。

插件的断点调试

  1. 通过命令打开Burp Suite;
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar [You path]burpsuite_community.jar 
  1. 在代码里面打上断点;

  2. 配置一个Remote JVM Debug
    Burp Suite Extension Development Guide

Burp Suite Extension Development Guide

  1. 加载上插件,开始调试。

UI界面

感觉UI这块内容不少,我后期单独写一篇新博客吧。可以点赞支持我加速。

Reference

发表评论

评论已关闭。

相关文章