说明:使用工具为IntelliJ IDEA,java11环境为java11。不同环境、编译器可能操作、语句可能会略有不同。
使用IntelliJ IDEA的gradle构建BurpExtender的环境依赖。
1.在IDEA新建一个gradle项目,命名随意:
2.在build.gradle文件中配置依赖,也就是加载burpsuite插件API。
配置如下:
plugins{id 'java'id 'com.github.johnrengelman.shadow'version '5.2.0'}group'org.example'versionrepositories {mavenCentral()}dependencies {testImplementationgroup: 'junit', name: 'junit', version:'4.12'//compile('net.portswigger.burp.extender:burp-extender-api:1.7.13')implementation('net.portswigger.burp.extender:burp-extender-api:2.3')implementation('com.intellij:forms_rt:7.0.3')}
其中,implementation('com.intellij:forms_rt:7.0.3')为UI的依赖,如果不需要UI,可以不配置该项。
3.配置完成后,点击右上角的锤子图标或ctrl+F9,进行构建。
4.构建完成后,在src\mian\java\下新建目录(软件包),命名为burp
5.再新建Java类,命名为BurpExtender
最终结果如下:
使插件能简单地输出hello world。
1.在BurpExtender编写代码如下:
packageburp;import java.awt.*;importjava.io.PrintWriter;public class BurpExtender implements IBurpExtender,IHttpListener{privateIBurpExtenderCallbacks callbacks;privateIExtensionHelpers helpers;//注册输出流private PrintWriter stdout;private PrintWriterstderr;// 实现接口IBurpExtender@Overridepublic voidregisterExtenderCallbacks(IBurpExtenderCallbacks callbacks) {this.callbacks = callbacks;helpers = callbacks.getHelpers();//设置插件名字callbacks.setExtensionName("BurpTest01");//获取输出流,输出位置为Outputstdout = new PrintWriter(callbacks.getStdout(), true);//获取输出流,输出位置为Errorsstderr = new PrintWriter(callbacks.getStderr(), true);//输出到OutPutstdout.println("Hello world");stderr.println("Hello errors");//注册Http监听器callbacks.registerHttpListener(this);}//实现接口IHttpListener@Overridepublic void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo){//输出messageInfo的信息到Outputstdout.println((messageIsRequest ? "HTTP request to " : "HTTP response from ") +messageInfo.getHttpService() +"[" + callbacks.getToolName(toolFlag) + "]");}}
2.点击绿色锤子,构建,确认无报错后,点击侧边栏的Gradle,展开shadow目录,双击,shadowJar:
如无报错,完成编译如下:
默认输出的路径在项目\build\libs目录下,建议使用everything工具搜索.jar,按时间排序
2.将编写的插件添加到burp extender中,查看Output和Errors:
开启代理,任意点击几个页面,查看Output:
编写简单的关键字检测。当检测到响应包包含给定的关键字时,对数据包进行标注。
现在,设置一些关键字,当检测到response数据包中存在关键字,则在HTTP history中,将其标记为粉色。
定义字符串数组如下
public final String[] keywords ={"secret","hidden","encry","decry","accesskey","access_token","accesstoken"};processHttpMessage函数改写如下
public void processHttpMessage(int toolFlag, boolean messageIsRequest,IHttpRequestResponse messageInfo){//注册responsebyte[] response = messageInfo.getResponse();//也可以用response!= null进行判定if(!messageIsRequest) {for (String keyword :keywords) {//helpers.indexOf为burpapi自带的函数,查找给定byte类型在目标中是否出现,如未出现返回-1//根据官方样例,使用getBytes()方法将字符串转为byte//第三个参数bool,true区分大小写,false不区分,最后2个int为搜索的起始位置和结束位置if (helpers.indexOf(response,keyword.getBytes(),false,0,response.length) >0) {//如果response中匹配到关键字,则标记为粉色messageInfo.setHighlight("pink");}}}}
结果如下:
使用IntelliJ IDEA,设计Burp Extender选项卡的ui。
先设置根据Form界面自动生成Java源码
1.在设置中,设置->编辑器->GUI设计器,勾选JAVA源代码:
2.在构建、执行、部署->Gradle中,将使用此工具构建和运行,更改为IntelliJ IDEA。
上述操作完成后,每次重新构建,UI的设计代码都会更新到对应的.java文件中。
3.在Burp文件夹中,创建UI。右键,新建->Swing UI设计器->GUI窗体,取名任意。文档中取名为bUI。
创建完成,在ui界面拖动需要的元素。
如图,为一个文本输入框,一个文本输入域,一个按钮。
为确保$$$getRootComponent$$$()自动生成,建议给每个ui元素设置单独的值(变量名):
4.在按钮右键,创建侦听器->ActionListener,便于后续填充需要实现的功能。
查看bUI.java,代码已自动生成:
5.修改BurpExtender,继承ITab并声明、注册界面,最终如下:
package burp;import java.awt.*;import java.io.PrintWriter;public class BurpExtender implements IBurpExtender,IHttpListener,ITab{private IBurpExtenderCallbacks callbacks;private IExtensionHelpers helpers;//注册输出private PrintWriter stdout;private PrintWriter stderr;//定义关键public final String[] keywords = {"secret", "hidden","encry", "decry", "accesskey","access_token", "accesstoken"};//注册guiprivate bUI bui;// 实现接口IBurpExtender@Overridepublic void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {this.callbacks = callbacks;helpers =callbacks.getHelpers();//设置插件名字callbacks.setExtensionName("BurpTest01");//获取输出流,输出位置为Outputstdout = new PrintWriter(callbacks.getStdout(), true);//获取输出流,输出位置为Errorsstderr = new PrintWriter(callbacks.getStderr(), true);//输出到OutPutstdout.println("Hello world");stderr.println("Hello errors");//注册界面bui = new bUI();callbacks.addSuiteTab(this);//注册Http监听callbacks.registerHttpListener(this);}//实现接口IHttpListener@Overridepublic void processHttpMessage(int toolFlag,boolean messageIsRequest, IHttpRequestResponse messageInfo) {byte[] response = messageInfo.getResponse();if(!messageIsRequest) {for (String keyword :keywords) {if (helpers.indexOf(response,keyword.getBytes(), false, 0, response.length) > 0) {// Sets the tab color as blue when keywords are foundmessageInfo.setHighlight("pink");}}}}//获取burp插件选项卡的名字@Overridepublic String getTabCaption() {return "BurpTest01";}//获取UI@Overridepublic Component getUiComponent() {return bui.$$$getRootComponent$$$();}}
添加插件,可以看到,UI已成功添加到burp上。
在ui上添加功能,使其能与burp进行联动。
目前,ui有一个按钮,一个文本输入框,一个文本域。
实现功能如下:a.当输入框内输入字符时,点击按钮,使burp可以获取到文本输入框的内容。
b.使burp能发送数据到ui当中。
实现a的功能
(1)在bUI.java中,声明变量InputText
private String InputText;(2)在ui初始化的过程中,已经给按钮创建了监听器。修改监听器的代码。当按下按钮时,按钮获取输入框的值,并赋值给InputText变量。
bUIBtn1.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//获取bUIInput输入框的值String InputText1 = bUIInput.getText();//赋值给InputTextInputText = InputText1;}});
(3)定义函数inputText,用于获取InputText的值。
public String inputText() {return InputText;}
至此,bUI.java完成。现在,对BurpExtender.java进行修改。在processHttpMessage()函数下,新增代码如下:
调用bUI的inputText()函数,获取InputText的值。如果值不为空,则输出到output模块中。
String InputText = bui.inputText();if (InputText != null) {stdout.println(InputText);}
将代码保存,打包,输入668877,点击button。
任意抓取数据包,查看output:
实现b的功能
(1)修改burpExtender,引入两个jar包。其中,java.net.url用于获取url,java.uitl.List用于获取header属性。同时,修改Bui的初始化。
......import java.net.URL;import java.util.List;public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks){... ...bui = new bUI(this);... ...}
(2)为对应无参初始化变为this,对应修改bUI的引用和定义。
......import burp.BurpExtender;public class bUI {... ...public bUI(BurpExtender burpExtender) {... ...}});}
(3)在bUI中,定义StringBuilder output,用于接收burpExtender的数据。定义函数output,用于输出数据到文本域中。
public class bUI {private final StringBuilder output;......public void appendOutput(String message) {output.append(message);output.append("\n");bUITXT.setText(output.toString());}......}
(4)将burpExtender中的processHttpMessage下分为两个部分。
如果是request数据包,将url、Host分别发送到ui中输出。
如果是response数据包,将statuscode、Date分别发送到ui中输出。
该代码在a功能的基础上修改。为此,将a功能,也就是输入框内的字符串作为开关。当输入框内无字符串时,则不发送数据。
先定义整个函数的框架
publicvoid processHttpMessage(int toolFlag, boolean messageIsRequest,IHttpRequestResponse messageInfo) {byte[] response = messageInfo.getResponse();byte[] request = messageInfo.getRequest();String InputText = bui.inputText();if (InputText != null) {/如果输入框无值,则不执行下列代码stdout = new PrintWriter(callbacks.getStdout(), true);stdout.println(InputText);if (messageIsRequest) {//处理request数据包}else{//处理reponse数据包}
处理request数据包如下,url需要通过toString()转字符串,header需要通过循环判断:
if (messageIsRequest) {IRequestInfo irequestinfo = helpers.analyzeRequest(messageInfo);//获取url并发送URL url = irequestinfo.getUrl();bui.appendOutput(url.toString());//获取headerList<String> headers = irequestinfo.getHeaders();for (String header : headers) {//循环获取参数,判断类型if (header.startsWith("Host")) {//如果是Host,则发送bui.appendOutput(header);}}}
处理response数据包如下,statuscode需要通过String.valueOf转字符串,header需要通过循环判断:
else{IResponseInfo iresponseInfo =helpers.analyzeResponse(messageInfo.getResponse());//获取statuscodeshort statusCode = iresponseInfo.getStatusCode();bui.appendOutput(String.valueOf(statusCode));List<String> headers = iresponseInfo.getHeaders();for(String header : headers) {//循环获取参数,判断类型if (header.startsWith("Date")) {//如果是Date,则发送bui.appendOutput(header);}}//下面为旧代码for (String keyword : keywords) {if(helpers.indexOf(response, keyword.getBytes(), false, 0,response.length) > 0) {// Sets the tab color asblue when keywords are foundmessageInfo.setHighlight("pink");}}}
将完成的代码保存,打包,输入框内输入任意字符串点击按钮,之后任意抓包:
关于数据包自动更改、自动调用poc攻击等功能的实现,请等待文章的后续连载。
https://blog.csdn.net/qq_28205153/article/details/113831967
https://github.com/PortSwigger/example-hello-world/blob/master/java/BurpExtender.java
https://github.com/PortSwigger/example-event-listeners/blob/master/java/BurpExtender.java#L16