编写第一个Burpsuite插件

前言

最近学了点java,所以打算试着写burpsuite插件来练练手,同时为了方便平时的渗透测试拓展一下burp.这次写的是检测响应包中的unicode码,并自动转换成中文.

API

要实现自动转换unicode为中文,最重要的一个问题是,如何去操控响应包.通过阅读burp官方提供的API参考,理出来我们要用到的接口主要有如下几个.

IBurpExtender

所有拓展都必须实现这个接口,并且实现的类名必须叫”BurpExtender”,存在于burp包中.

IBurpExtender中只有一个方法需要实现.

  • void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks)

    当拓展被加载时自动调用此方法,也就是说这就是我们的入口了.

    参数为IBurpExtenderCallbacks接口的实例callbacks

IBurpExtenderCallbacks

Burp Suite使用这个接口传递给扩展一组回调方法,扩展可以使用这些方法在Burp内执行各种操作.

一些可能用到的方法.

  • java.io.OutputStream getStdout()

    此方法用于获取当前拓展的标准输出流。扩展应该将所有输出写入此流,允许Burp用户配置如何从UI内处理输出.

  • java.io.OutputStream getStderr()

    此方法用于获取当前拓展的标准错误流。扩展应该将所有错误消息写入此流,允许Burp用户配置如何从UI中处理输出.

  • void setExtensionName(java.lang.String name)

    此方法用于设置当前拓展的显示名称,该名称将显示在扩展器工具的用户界面中.

  • IExtensionHelpers getHelpers()

    此方法用于获取IExtensionHelpers对象,该扩展名可用于执行许多有用的任务.

  • void registerHttpListener(IHttpListener listener)

    这个方法用来注册一个监听器,这个监听器将被通知任何Burp工具所做的请求和响应。扩展可以通过注册HTTP侦听器来执行自定义分析或修改这些消息

IExtensionHelpers

这个接口包含了一些辅助方法,这些方法可以用来协助Burp扩展中出现的各种常见任务。扩展可以调用IBurpExtenderCallbacks.getHelpers来获得这个接口的一个实例.

  • IRequestInfo analyzeRequest(byte[] request)

    用于解析HTTP请求,并获得关于该请求的详细信息,返回IRequestInfo对象

  • IResponseInfo analyzeResponse(byte[] response)

    用于解析HTTP响应,并获得关于该响应的详细信息,返回IResponseInf对象

  • byte[] buildHttpMessage(java.util.List\ headers, byte[] body)

    这个方法构建一个包含指定头和消息主体的HTTP消息。如果适用,Content-Length头将根据正文的长度添加或更新

IRequestInfo

该接口用于检索关于HTTP请求的关键细节。通过调用IExtensionHelpers.analyzeRequest(),扩展可以获得给定请求的IRequestInfo对象.

  • java.lang.String getMethod()

    此方法用于获取请求中使用的HTTP方法

  • java.net.URL getUrl()

    此方法用于获取请求中的URL

  • java.util.List\ getHeaders()

    此方法用于获取请求中包含的HTTP标头

  • java.util.List\ getParameters()

    此方法用于获取请求中包含的参数

  • int getBodyOffset()

    此方法用于获取消息正文开始的请求内的偏移量.

IResponseInfo

该接口用于检索有关HTTP响应的关键细节。扩展可以通过调用IExtensionHelpers.analyzeResponse()来获得给定响应的IResponseInfo对象.

我们这次主要用到的就是这个接口.

  • java.util.List\ getHeaders()

    此方法用于获取响应中包含的HTTP头.

  • int getBodyOffset()

    此方法用于获取消息正文开始的响应中的偏移量.

  • short getStatusCode()

    此方法用于获取响应中包含的HTTP状态码.

  • java.util.List\ getCookies()

    此方法用于获取响应中设置的HTTP Cookie的详细信息.

IHttpRequestResponse

此接口用于检索和更新有关HTTP消息的详细信息.

  • byte[] getRequest()

    此方法用于取得请求消息.

  • byte[] getResponse()

    此方法用于获得响应消息.

    我们要修改响应包就需要先用这个方法获得响应消息.

  • void setResponse(byte[] message)

    此方法用于更新响应消息.

    我们修改完响应包之后,需要用这个方法来更新响应包.

  • void setRequest(byte[] message)

    此方法用于更新请求消息.

IHttpListener

扩展可以实现这个接口,然后调用IBurpExtenderCallbacks.registerHttpListener()来注册一个HTTP监听器。监听器将收到任何Burp工具发出的请求和响应的通知。扩展可以通过注册HTTP监听器来执行自定义分析或修改这些消息.

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

    当一个HTTP请求即将被发出,并且当一个HTTP响应被接收时,这个方法被自动调用.

    参数:

    • toolFlag: 不同的flag代表不同的Burp tool.参考Constant Field Values
    • messageIsRequest: 判断消息是请求还是响应
    • messageInfo: 要处理的请求或响应消息

编写Unicode转中文拓展

首先,在burpsuite中把api导出到一个文件夹,

我使用的IDE是Eclipse,在项目里新建一个”burp”包,并导入刚才导出的api.

然后创建一个BurpExtender类,开始插件代码的编写.

https://github.com/sn00pyd0g3/burpExtender/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package burp;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.PrintWriter;
public class BurpExtender implements IBurpExtender, IHttpListener{
private IExtensionHelpers helpers;
private PrintWriter stdout;
private String ExtenderName = "Unicode decoder";
@Override
public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {
//64:REPEATER 32:INTRUDER 16:SCANNER
if(toolFlag == 64 || toolFlag == 32 || toolFlag == 16) {
if(!messageIsRequest) { //只处理响应消息
byte[] response = messageInfo.getResponse(); //取得响应消息
IResponseInfo analyzedResponse = helpers.analyzeResponse(response); //解析响应消息
List<String> headers = analyzedResponse.getHeaders(); //取得响应头
String resp = new String(messageInfo.getResponse()); //把响应包转换成字符串
//截取出body字符串
int bodyOffset = analyzedResponse.getBodyOffset();
String body = resp.substring(bodyOffset);
body = unicodeToString(body);
byte[] bodybyte = body.getBytes(); ////body还原成字节码
messageInfo.setResponse(helpers.buildHttpMessage(headers, bodybyte)); //构建响应消息并更新
}
}
}
@Override
public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {
stdout = new PrintWriter(callbacks.getStdout(), true);
stdout.println(ExtenderName);
helpers = callbacks.getHelpers();
//设置拓展名
callbacks.setExtensionName(ExtenderName);
//注册HttpListener,处理请求和响应
callbacks.registerHttpListener(this);
}
//unicode转中文
public static String unicodeToString(String str) {
Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
Matcher matcher = pattern.matcher(str);
char ch;
while (matcher.find()) {
ch = (char) Integer.parseInt(matcher.group(2), 16);
str = str.replace(matcher.group(1), ch + "");
}
return str;
}
}

刚开始可能读了API文档还是没思路,这时候可以去找些类似的拓展源码来看一下.

光看文档的解析也很难理解处理流程,通过观察接口中方法的参数和返回值类型可以比较容易的理出各个接口的调用链,实现起来就有思路了.

比如这个unicode解码,大致的思路就是:

  • 首先,必须实现IBurpExtender,这是burp规定的.在它的registerExtenderCallbacks方法中,设置了拓展名;创建了标准输出流来打印出拓展名
  • 因为我们要修改HTTP响应,所以继承了IHttpListener,并且在registerExtenderCallbacks中注册了HttpListener.(这些都是根据文档来的)
  • 接着重写IHttpListenerprocessHttpMessage方法,先获得响应消息,再截取出body部分,进行修改(解码)和更新.

最后,打包成jar文件.

右键项目名,选择Export,

选择Jar file,

最后就可以在burpsuite中加载插件了.

关闭插件:

启用插件:

总结

java不熟,写起来很费劲,以后有时间,想写个根据网站信息(域名,关键词)自动生成intruder paload的插件.😵

好,又水了一篇.

Refer

https://portswigger.net/burp/extender/api/

http://www.code2sec.com/2017/01/07/burpsuite%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91tips%EF%BC%9A%E8%AF%B7%E6%B1%82%E5%93%8D%E5%BA%94%E5%8F%82%E6%95%B0%E7%9A%84aes%E5%8A%A0%E8%A7%A3%E5%AF%86/