平常每次出一个漏洞都会出一个burp被动扫描的插件 所以可以提前做好一个模板
burp插件开发注意事项
- 所有的burp插件都必须实现IBurpExtender这个接口
- 实现类的包名称必须是burp
- 实现类的名称必须是BurpExtender
- 实现类比较是public的
- 实现类必须有默认构造函数(public,无参),如果没有定义构造函数就是默认构造函数
maven
<dependency><groupId>net.portswigger.burp.extender</groupId><artifactId>burp-extender-api</artifactId><version>LATEST</version></dependency>
打包

模板
UI
设置一个大众化的UI
package burp;import java.awt.Component;import java.io.PrintWriter;import java.net.URL;import java.util.ArrayList;import java.util.List;//import java.util.Random;import javax.swing.JScrollPane;import javax.swing.JSplitPane;import javax.swing.JTabbedPane;import javax.swing.JTable;import javax.swing.SwingUtilities;import javax.swing.table.AbstractTableModel;import javax.swing.table.TableModel;//IMessageEditor使用IMessageEditorController接口获取当前显示的消息的详细信息//扩展可以实现这个IScannerCheck接口,然后调用 IBurpExtenderCallbacks.registerScannerCheck()来注册一个自定义的 Scanner 检查。//Itab这个接口用于使用 IBurpExtenderCallbacks.addSuiteTab ()之类的方法为 Burp 提供将添加到 Burp 的 UI 中的自定义选项卡的详细信息。public class BurpExtender extends AbstractTableModel implements IBurpExtender, IScannerCheck, ITab, IMessageEditorController {//IBurpExtenderCallbacks接口类是IBurpExtender接口的实 现类与Burp其他各个组件(Scanner、Intruder、Spider......)、各个通信对象 (HttpRequestResponse、HttpService、SessionHandlingAction)之间的连接private IBurpExtenderCallbacks callbacks;//IExtensionHelpers接口包含许多辅助方法,扩展可以使用这些方法来协助 Burp 扩展出现的各种常见任务//比如向 HTTP 请求添加新参数,分析 HTTP 请求private IExtensionHelpers helpers;//分隔面板,SplitPane用于分隔两个(只能两个)组件,分割request和responseprivate JSplitPane splitPane;//IMessageEditor用于为扩展提供 Burp 的 HTTP 消息编辑器的实例,以便扩展在其自己的 UI 中使用private IMessageEditor requestViewer;private IMessageEditor responseViewer;private final List<LogEntry> log = new ArrayList<>();//IHttpRequestResponse此接口用于检索和更新有关 HTTP 消息的详细信息。private IHttpRequestResponse currentlyDisplayedItem;private String ExtenderName = "SpringCore";private PrintWriter stdout;//此方法将在扩展加载后被调用,它注册了一个 IBurpExtenderCallbacks 接口的实例, IBurpExtenderCallbacks 接口提供了许多在开发插件过程中常用的一些操作。@Overridepublic void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) {//获取burp提供的标准输出流this.stdout = new PrintWriter(callbacks.getStdout(), true);//打印到标准输出流this.stdout.println(this.ExtenderName);//保留对callbacks的引用this.callbacks = callbacks;//此方法用于获取IExtensionHelpers对象,扩展程序可以使用该对象执行许多有用的任务。this.helpers = callbacks.getHelpers();//设置插件的名称callbacks.setExtensionName(this.ExtenderName);//调用 IBurpExtenderCallbacks.registerScannerCheck()来注册一个自定义的 Scanner 检查callbacks.registerScannerCheck(this);//创建一个Swing线程用于我们的burp的UISwingUtilities.invokeLater(new Runnable() {@Overridepublic void run() {BurpExtender.this.splitPane = new JSplitPane(0);BurpExtender.Table logTable = new BurpExtender.Table(BurpExtender.this);//创建一个滚动条JScrollPane scrollPane = new JScrollPane(logTable);//设置滚动条位置左侧或上方BurpExtender.this.splitPane.setLeftComponent(scrollPane);JTabbedPane tabs = new JTabbedPane();//此方法用于创建 Burp 的 HTTP 消息编辑器的新实例,以便扩展在其自己的 UI 中使用。BurpExtender.this.requestViewer = callbacks.createMessageEditor(BurpExtender.this, false);BurpExtender.this.responseViewer = callbacks.createMessageEditor(BurpExtender.this, false);tabs.addTab("Request", BurpExtender.this.requestViewer.getComponent());tabs.addTab("Response", BurpExtender.this.responseViewer.getComponent());//将组件设置在分隔线的右侧或下方BurpExtender.this.splitPane.setRightComponent(tabs);//customizeUiComponent方法用于自定义符合 Burp 的 UI 风格的 UI 组件,包括字体大小、颜色、表格行距等。callbacks.customizeUiComponent(BurpExtender.this.splitPane);callbacks.customizeUiComponent(logTable);callbacks.customizeUiComponent(scrollPane);callbacks.customizeUiComponent(tabs);//addSuiteTab方法用于将自定义选项卡添加到 Burp Suite 主窗口。callbacks.addSuiteTab(BurpExtender.this);}});}//设置我们的被动扫描@Overridepublic List<IScanIssue> doPassiveScan(IHttpRequestResponse baseRequestResponse) {//等会要添加被动扫描代码return null;}//设置我们的主动扫描@Overridepublic List<IScanIssue> doActiveScan(IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) {return null;}//当报告同一URL有多个问题时,将调用此方法//漏洞去重函数,可以根据自己的需求,根据不同的参数来判断是否重复,比如URL、漏洞名称等@Overridepublic int consolidateDuplicateIssues(IScanIssue existingIssue, IScanIssue newIssue) {/*** if (existingIssue.getIssueName().equals(newIssue.getIssueName()))* return -1;* else return 0;*/return 0;}//JTable使用此方法来确定它应该显示多少行@Overridepublic int getRowCount() {return this.log.size();}//JTable使用此方法来确定默认情况下它应该创建和显示多少列@Overridepublic int getColumnCount() {return 3;}//返回列的默认名称@Overridepublic String getColumnName(int columnIndex) {switch (columnIndex) {case 0:return "Vuln";case 1:return "URL";case 2:return "Position";}return "";}@Overridepublic Class<?> getColumnClass(int columnIndex) {return String.class;}//返回值@Overridepublic Object getValueAt(int rowIndex, int columnIndex) {LogEntry logEntry = this.log.get(rowIndex);switch (columnIndex) {case 0:return "SpringCoreRCE";case 1:return logEntry.url.toString();case 2:return logEntry.position;}return "";}//设置Tab标签名称@Overridepublic String getTabCaption() {return "YanMu";}//设置Tab标签的内容@Overridepublic Component getUiComponent() {return this.splitPane;}//返回相关request信息@Overridepublic byte[] getRequest() {return this.currentlyDisplayedItem.getRequest();}//返回相关response信息@Overridepublic byte[] getResponse() {return this.currentlyDisplayedItem.getResponse();}//返回相关HttpService信息@Overridepublic IHttpService getHttpService() {return this.currentlyDisplayedItem.getHttpService();}private class Table extends JTable {public Table(TableModel tableModel) {super(tableModel);}//更新表格@Overridepublic void changeSelection(int row, int col, boolean toggle, boolean extend) {//返回此列表中指定位置的元素BurpExtender.LogEntry logEntry = BurpExtender.this.log.get(row);BurpExtender.this.requestViewer.setMessage(logEntry.requestResponse.getRequest(), true);BurpExtender.this.responseViewer.setMessage(logEntry.requestResponse.getResponse(), false);BurpExtender.this.currentlyDisplayedItem = logEntry.requestResponse;super.changeSelection(row, col, toggle, extend);}}//检测变化private static class LogEntry {final int tool;final IHttpRequestResponse requestResponse;final URL url;final String position;LogEntry(int tool, IHttpRequestResponse requestResponse, URL url, String position) {this.tool = tool;this.requestResponse = requestResponse;this.url = url;this.position = position;}}}
DNS
被动扫描DNSlog的出场率一直很高
burp自带的DNSlog
//与dnslog平台进行交互IBurpCollaboratorClientContext context= this.callbacks.createBurpCollaboratorClientContext();// 一个burp提供的dnslog平台String dnslog = context.generatePayload(true);List<IBurpCollaboratorInteraction> dnsres = new ArrayList<>();this.stdout.println(dnslog);//替换以后String.format(),发送请求IHttpRequestResponse resp = this.callbacks.makeHttpRequest(iHttpService, new_Request);//休眠2秒Thread.sleep(2000);// 返回的是一个dns响应数组dnsres = context.fetchCollaboratorInteractionsFor(dnslog);this.stdout.println(dnsres);if(!dnsres.isEmpty()){this.stdout.println("found!!!");// 漏洞存在就更新表格中存在漏洞那一行的数据//LogEntry logEntry = new LogEntry(url, "finished", "vul!!!", resp);//log.set(row, logEntry);// 这个方法是swing中的一个方法,会通知表格更新指定行的数据//fireTableRowsUpdated(row, row);break;}
sprigcore为演示
解释基本都在注释中
package burp;import java.awt.Component;import java.io.PrintWriter;import java.net.URL;import java.util.ArrayList;import java.util.List;import java.util.Random;//import java.util.Random;import javax.swing.JScrollPane;import javax.swing.JSplitPane;import javax.swing.JTabbedPane;import javax.swing.JTable;import javax.swing.SwingUtilities;import javax.swing.table.AbstractTableModel;import javax.swing.table.TableModel;//IMessageEditor使用IMessageEditorController接口获取当前显示的消息的详细信息//扩展可以实现这个IScannerCheck接口,然后调用 IBurpExtenderCallbacks.registerScannerCheck()来注册一个自定义的 Scanner 检查。//Itab这个接口用于使用 IBurpExtenderCallbacks.addSuiteTab ()之类的方法为 Burp 提供将添加到 Burp 的 UI 中的自定义选项卡的详细信息。public class BurpExtender extends AbstractTableModel implements IBurpExtender, IScannerCheck, ITab, IMessageEditorController {//IBurpExtenderCallbacks接口类是IBurpExtender接口的实 现类与Burp其他各个组件(Scanner、Intruder、Spider......)、各个通信对象 (HttpRequestResponse、HttpService、SessionHandlingAction)之间的连接private IBurpExtenderCallbacks callbacks;//IExtensionHelpers接口包含许多辅助方法,扩展可以使用这些方法来协助 Burp 扩展出现的各种常见任务//比如向 HTTP 请求添加新参数,分析 HTTP 请求private IExtensionHelpers helpers;//分隔面板,SplitPane用于分隔两个(只能两个)组件,分割request和responseprivate JSplitPane splitPane;//IMessageEditor用于为扩展提供 Burp 的 HTTP 消息编辑器的实例,以便扩展在其自己的 UI 中使用private IMessageEditor requestViewer;private IMessageEditor responseViewer;private final List<LogEntry> log = new ArrayList<>();//IHttpRequestResponse此接口用于检索和更新有关 HTTP 消息的详细信息。private IHttpRequestResponse currentlyDisplayedItem;private String ExtenderName = "SpringCore";private PrintWriter stdout;//此方法将在扩展加载后被调用,它注册了一个 IBurpExtenderCallbacks 接口的实例, IBurpExtenderCallbacks 接口提供了许多在开发插件过程中常用的一些操作。@Overridepublic void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) {//获取burp提供的标准输出流this.stdout = new PrintWriter(callbacks.getStdout(), true);//打印到标准输出流this.stdout.println(this.ExtenderName);//保留对callbacks的引用this.callbacks = callbacks;//此方法用于获取IExtensionHelpers对象,扩展程序可以使用该对象执行许多有用的任务。this.helpers = callbacks.getHelpers();//设置插件的名称callbacks.setExtensionName(this.ExtenderName);//调用 IBurpExtenderCallbacks.registerScannerCheck()来注册一个自定义的 Scanner 检查callbacks.registerScannerCheck(this);//创建一个Swing线程用于我们的burp的UISwingUtilities.invokeLater(new Runnable() {@Overridepublic void run() {BurpExtender.this.splitPane = new JSplitPane(0);BurpExtender.Table logTable = new BurpExtender.Table(BurpExtender.this);//创建一个滚动条JScrollPane scrollPane = new JScrollPane(logTable);//设置滚动条位置左侧或上方BurpExtender.this.splitPane.setLeftComponent(scrollPane);JTabbedPane tabs = new JTabbedPane();//此方法用于创建 Burp 的 HTTP 消息编辑器的新实例,以便扩展在其自己的 UI 中使用。BurpExtender.this.requestViewer = callbacks.createMessageEditor(BurpExtender.this, false);BurpExtender.this.responseViewer = callbacks.createMessageEditor(BurpExtender.this, false);tabs.addTab("Request", BurpExtender.this.requestViewer.getComponent());tabs.addTab("Response", BurpExtender.this.responseViewer.getComponent());//将组件设置在分隔线的右侧或下方BurpExtender.this.splitPane.setRightComponent(tabs);//customizeUiComponent方法用于自定义符合 Burp 的 UI 风格的 UI 组件,包括字体大小、颜色、表格行距等。callbacks.customizeUiComponent(BurpExtender.this.splitPane);callbacks.customizeUiComponent(logTable);callbacks.customizeUiComponent(scrollPane);callbacks.customizeUiComponent(tabs);//addSuiteTab方法用于将自定义选项卡添加到 Burp Suite 主窗口。callbacks.addSuiteTab(BurpExtender.this);}});}//设置我们的被动扫描@Overridepublic List<IScanIssue> doPassiveScan(IHttpRequestResponse baseRequestResponse) {//IHttpRequestResponse接口用于检索和更新有关 HTTP 消息的详细信息try {//此方法可用于分析 HTTP 请求,并获取有关它的各种关键细节。IRequestInfo analyzeRequest = this.helpers.analyzeRequest(baseRequestResponse);//此方法用于检索请求消息。byte[] request = baseRequestResponse.getRequest();//此方法用于检索此请求/响应的 HTTP 服务。IHttpService httpService = baseRequestResponse.getHttpService();boolean flag = false;URL url = analyzeRequest.getUrl();String subfix = getSubfix(url.toString());//设置不扫描的路径String blacklist = ".js|.png|.jpg|.jpeg|.svg|.gif|.ico|.css";if (!subfix.isEmpty() && blacklist.contains(subfix)) {this.stdout.println(subfix + " no check");return null;}String host = httpService.getHost();int port = httpService.getPort();String protocol = httpService.getProtocol();boolean https = false;if (protocol.equals("https")){https = true;}List<IParameter> paramsList = analyzeRequest.getParameters();byte getCode = 0;byte postCode = 1;this.stdout.println("checking..." + analyzeRequest.getUrl());//此方法根据提供的详细信息构造一个 IParameter 对象。IParameter getParam = this.helpers.buildParameter("class.mod%75le.classLoader.DefaultAssertionStatus", "true", getCode);IParameter postParam = this.helpers.buildParameter("class.mod%75le.classLoader.DefaultAssertionStatus", "true", postCode);request = this.helpers.updateParameter(request, getParam);//此方法更新 HTTP 请求中的参数值,如果适当,则更新 Content-Length 标头。request = this.helpers.updateParameter(request, postParam);//此方法可用于发出 HTTP 请求并检索其响应。IHttpRequestResponse newRequest2 = this.callbacks.makeHttpRequest(httpService, request);//此方法可用于分析 HTTP 响应,并获取关于它的各种关键细节。IResponseInfo analyzeRequest2 = this.helpers.analyzeResponse(newRequest2.getResponse());if (analyzeRequest2.getStatusCode() == 200){flag = true;}if (flag) {//制造IParameter getParam2 = this.helpers.buildParameter("class.mod%75le.classLoader.DefaultAssertionStatus", createRandomStr(4), getCode);IParameter postParam2 = this.helpers.buildParameter("class.mod%75le.classLoader.DefaultAssertionStatus", createRandomStr(4), postCode);//更新请求参数request = this.helpers.updateParameter(request, getParam2);request = this.helpers.updateParameter(request, postParam2);IHttpRequestResponse newRequest3 = this.callbacks.makeHttpRequest(httpService, request);IResponseInfo analyzeRequest3 = this.helpers.analyzeResponse(newRequest3.getResponse());if (analyzeRequest3.getStatusCode() == 400){synchronized (this.log) {int row = this.log.size();//漏洞利用成功返回表格数据this.log.add(new LogEntry(4, this.callbacks.saveBuffersToTempFiles(newRequest3), this.helpers.analyzeRequest(baseRequestResponse).getUrl(), null));fireTableRowsInserted(row, row);}}}} catch (Exception e) {this.stdout.print(e);return null;}return null;}//Url解析public String getSubfix(String url) {int index = url.indexOf("?");String tmp = "";if (index != -1) {tmp = url.substring(0, index);} else {tmp = url;}int index2 = tmp.lastIndexOf("/");String tmp2 = tmp.substring(index2 + 1);int index3 = tmp2.lastIndexOf(".");return tmp2.substring(index3 + 1);}//设置我们的随机数public String createRandomStr(int length) {String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";Random random = new Random();StringBuffer stringBuffer = new StringBuffer();for (int i = 0; i < length; i++) {int number = random.nextInt(62);stringBuffer.append(str.charAt(number));}return stringBuffer.toString();}//设置我们的主动扫描@Overridepublic List<IScanIssue> doActiveScan(IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) {return null;}//当报告同一URL有多个问题时,将调用此方法//漏洞去重函数,可以根据自己的需求,根据不同的参数来判断是否重复,比如URL、漏洞名称等@Overridepublic int consolidateDuplicateIssues(IScanIssue existingIssue, IScanIssue newIssue) {/*** if (existingIssue.getIssueName().equals(newIssue.getIssueName()))* return -1;* else return 0;*/return 0;}//JTable使用此方法来确定它应该显示多少行@Overridepublic int getRowCount() {return this.log.size();}//JTable使用此方法来确定默认情况下它应该创建和显示多少列@Overridepublic int getColumnCount() {return 3;}//返回列的默认名称@Overridepublic String getColumnName(int columnIndex) {switch (columnIndex) {case 0:return "Vuln";case 1:return "URL";case 2:return "Position";}return "";}@Overridepublic Class<?> getColumnClass(int columnIndex) {return String.class;}//返回值@Overridepublic Object getValueAt(int rowIndex, int columnIndex) {LogEntry logEntry = this.log.get(rowIndex);switch (columnIndex) {case 0:return "SpringCoreRCE";case 1:return logEntry.url.toString();case 2:return logEntry.position;}return "";}//设置Tab标签名称@Overridepublic String getTabCaption() {return this.ExtenderName;}//设置Tab标签的内容@Overridepublic Component getUiComponent() {return this.splitPane;}//返回相关request信息@Overridepublic byte[] getRequest() {return this.currentlyDisplayedItem.getRequest();}//返回相关response信息@Overridepublic byte[] getResponse() {return this.currentlyDisplayedItem.getResponse();}//返回相关HttpService信息@Overridepublic IHttpService getHttpService() {return this.currentlyDisplayedItem.getHttpService();}private class Table extends JTable {public Table(TableModel tableModel) {super(tableModel);}//更新表格@Overridepublic void changeSelection(int row, int col, boolean toggle, boolean extend) {//返回此列表中指定位置的元素BurpExtender.LogEntry logEntry = BurpExtender.this.log.get(row);BurpExtender.this.requestViewer.setMessage(logEntry.requestResponse.getRequest(), true);BurpExtender.this.responseViewer.setMessage(logEntry.requestResponse.getResponse(), false);BurpExtender.this.currentlyDisplayedItem = logEntry.requestResponse;super.changeSelection(row, col, toggle, extend);}}//检测变化private static class LogEntry {final int tool;final IHttpRequestResponse requestResponse;final URL url;final String position;LogEntry(int tool, IHttpRequestResponse requestResponse, URL url, String position) {this.tool = tool;this.requestResponse = requestResponse;this.url = url;this.position = position;}}}


