BurpSuite插件开发指南之 API(上下篇) 0x00 前言 BurpSuite 作为一款 Web 安全测试的利器,得益于其强大的代理,操控数据的功能,在 Web 安全测试过程中,为我们省下了不少时间和精力专注于漏洞的挖掘和测试。更重要的是 BurpSuite 提供了插件开发接口,Web 安全测试人员可以根据实际需求自己开发出提高安全测试效率的插件,虽然 BApp Store 上面已经提供了很多插件,其中也不乏优秀好用的插件,但是作为一名专业的 Web 安全测试人员,有必要熟练掌握 BurpSuite 插件开发技术。国内针对 BurpSuite 插件开发的技术文档并不是很多,也不够全面,《BurpSuite 插件开发指南》系列文章作为 BurpSuite 非官方非权威开发指南,希望在这块填补一些空白。文章中难免有纰漏,望读者自行验证并及时指出。
《BurpSuite 插件开发指南》系列文章如下:
《BurpSuite插件开发指南之 API 篇》
《BurpSuite插件开发指南之 Java 篇》
《BurpSuite插件开发指南之 Python 篇》
在第一篇文章中,笔者将会介绍 BurpSuite 所提供的开发接口的功能和参数说明,但是不会对 BurpSuite 本身所提供的功能作太多说明。剩余两篇则会分别使用案例阐述 Java 和 Python 进行插件开发的技术。其中会用到 Java 的 Swing 包进行 GUI 编程。
0x01 BurpSuite 插件开发说明 BurpSuite 插件扩展开发所支持的编程语言有 Java 和 Python,使用这两种开发语言开发的插件在功能上并没有太多区别,使用原生的 Java 开发的插件要比 Python 开发的插件,加载和执行效率更高。所以,笔者推荐使用 Java 作为插件开发的首选语言。
SDK:
开发文档: BurpSuite 插件开发文档在线地址: BurpSuite Extension Dev Doc 或者可以在 BurpSuite 程序的 “Extender” 标签下的 “APIs” 子标签里找到。
SDK 包: 目前,BurpSuite 官网已经不再提供 SDK 包文件的下载,读者可以从 BurpSuite 程序中导出。
JPython:使用 Python 开发插件,需要先安装 JPython 。
注:导出 SDK 包文件操作步骤: “Extender — APIs - Save interface files(左下角)”
开发 IDE:
使用 Java 开发插件的读者可以使用 Eclipse 这款强大的 IDE 。当然也可以使用其他 Java 开发 IDE,如 IDEA。
使用 Python 开发插件的读者也可以使用 Eclipse (需要安装 PyDev 插件)作为插件开发的 IDE,或者使用 Notepad++, PyCharm。
注:推荐使用 Eclipse 作为插件开发 IDE, 除了 Java 之外,Eclipse 对 JPython 也有很好的支持。
辅助工具:
学习资料:
BurpSuite 官方并未提供详细的开发文档,只有少量的开发实例,可以 在此找到 。不过,BurpSuite 官方建立了 插件开发者社区 和 博客 ,可以帮助开发者解答疑问。
在 乌云Drops 上也有两篇专门介绍 BurpSuite 插件开发的文章,读者可以参考:
相较于阅读许多参考资料从零开始编写插件,笔者更推荐在熟悉了开发文档后直接在已有的源码中“照猫画虎”进行插件的开发。现有的插件,读者可以在 BApp Store 中找到,Python 版本的插件可以直接查看源码进行学习,Java 版本的插件可以在反编译后查看其源码进行学习。
注:安装了 BApp Store 中的插件后,会在 BurpSuite 所在目录下的 bapps 文件夹中找到插件文件。
插件开发“方法论”:
插件型的应用程序在设计时就一定会考虑插件的开发,因此,主程序与插件之间必然有一种“约定”,在开发插件的过程中,只需按照程序开发者设计的这种“约定”开发就好了,读者在阅读参考官方开发文档时只需注意以下三点:
接口方法功能
接口方法入参(参数类型和参数个数)
接口方法的返回值(返回值类型)
在关注上述三点以后,就可以把多个接口方法联系在一起,组织起一定的逻辑,这样,开发的思路就顺理成章了。
0x02 API 参考 本节将对 BurpSuite 的官方文档做简要的说明,并给出简单的 Demo code,各个接口具体的使用实例,可以在笔者后续的两篇文章中看到。
IBurpExtender 接口 public interface IBurpExtender 所有的扩展必须实现此接口,实现的类名必须为“BurpExtender”。在 burp 包中,必须申明为 public ,并且必须提供一个默认的构造器。此接口实现了以下方法:
1 2 3 #!java void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks)
此方法将在扩展加载后被调用,它注册了一个 IBurpExtenderCallbacks 接口的实例, IBurpExtenderCallbacks 接口提供了许多在开发插件过程中常用的一些操作。
参数说明:
callbacks 是一个 IBurpExtenderCallbacks 对象。
Demo code:
1 2 3 4 5 6 7 8 package burp; public class BurpExtender implements IBurpExtender { @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ } }
IBurpExtenderCallbacks public interface IBurpExtenderCallbacks 此接口中实现的方法和字段在插件开发过程中会经常使用到。 Burp Suite 利用此接口向扩展中传递了许多回调方法,这些回调方法可被用于在 Burp 中执行多个操作。当扩展被加载后,Burp 会调用 registerExtenderCallbacks() 方法,并传递一个 IBurpExtenderCallbacks 的实例。扩展插件可以通过这个实例调用很多扩展 Burp 功能必需的方法。如:设置扩展插件的属性,操作 HTTP 请求和响应以及启动其他扫描功能等等。
此接口提供了很多的方法和字段,在此不一一列举,具体的说明可以在 burp SDK 中的 IBurpExtenderCallbacks.java 或 https://portswigger.net/burp/extender/api/burp/IBurpExtenderCallbacks.html 中查看。
Demo code:
1 2 3 4 5 6 7 8 9 package burp; public class BurpExtender implements IBurpExtender { @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ callbacks.setExtensionName("Her0in" ); } }
Burp 的作者在设计上下文菜单功能中采用了工厂模式的设计模式,扩展可以实现此接口,然后调用 IBurpExtenderCallbacks.registerContextMenuFactory() 注册自定义上下文菜单项的工厂。
此接口提供了如下方法:
1 2 #!java java.util .List <javax.swing .JMenuItem > createMenuItems(IContextMenuInvocation invocation)
当用户在 Burp 中的任何地方调用一个上下文菜单时,Burp 则会调用这个工厂方法。此方法会根据菜单调用的细节,提供应该被显示在上下文菜单中的任何自定义上下文菜单项。
参数说明:
invocation - 一个实现 IMessageEditorTabFactory 接口的对象, 通过此对象可以获取上下文菜单调用的细节。
返回值:
此工厂方法将会返回需要被显示的自定义菜单项的一个列表(包含子菜单,checkbox 菜单项等等), 若无菜单项显示,此工厂方法会返回 null 。
Demo code:
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 #!java package burp; import java.util.ArrayList; import java.util.List; import javax.swing.JMenu; import javax.swing.JMenuItem; public class BurpExtender implements IBurpExtender, IContextMenuFactory{ @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ callbacks.setExtensionName("Her0in"); callbacks.registerContextMenuFactory(this); } @Override public List<JMenuItem> createMenuItems(final IContextMenuInvocation invocation) { List<JMenuItem> listMenuItems = new ArrayList<JMenuItem>(); //子菜单 JMenuItem menuItem; menuItem = new JMenuItem("子菜单测试"); //父级菜单 JMenu jMenu = new JMenu("Her0in"); jMenu.add(menuItem); listMenuItems.add(jMenu); return listMenuItems; } }
此接口被用于获取当 Burp 调用扩展提供的 IContextMenuFactory 工厂里的上下文菜单时的一些细节,如能获取到调用了扩展提供的自定义上下文菜单的 Burp 工具名称(在 IBurpExtenderCallbacks 中定义)或功能组件的名称(在 IContextMenuInvocation 中定义)。
此接口提供了如下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #!java // 此方法可被用于获取本地Java输入事件,并作为上下文菜单调用的触发器 java.awt.event.InputEvent getInputEvent() // 此方法被用于获取上下文中被调用的菜单 byte getInvocationContext() // 此方法被用于获取用户选中的 Scanner 问题的细节 IScanIssue[] getSelectedIssues() // 此方法被用于获取当前显示的或用户选中的 HTTP 请求/响应的细节 IHttpRequestResponse[] getSelectedMessages() // 此方法被用于获取用户所选的当前消息的界限(消息需可适用) int[] getSelectionBounds() // 此方法被用于获取调用上下文菜单的 Burp 工具 int getToolFlag()
Demo code:
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 #!java package burp; import java.util.ArrayList; import java.util.List; import javax.swing.JMenu; import javax.swing.JMenuItem; public class BurpExtender implements IBurpExtender, IContextMenuFactory{ @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ callbacks.setExtensionName("Her0in"); callbacks.registerContextMenuFactory(this); } @Override public List<JMenuItem> createMenuItems(final IContextMenuInvocation invocation) { List<JMenuItem> listMenuItems = new ArrayList<JMenuItem>(); // 菜单只在 REPEATER 工具的右键菜单中显示 if(invocation.getToolFlag() == IBurpExtenderCallbacks.TOOL_REPEATER){ //子菜单 JMenuItem menuItem; menuItem = new JMenuItem("子菜单测试"); //父级菜单 JMenu jMenu = new JMenu("Her0in"); jMenu.add(menuItem); listMenuItems.add(jMenu); } return listMenuItems; } }
ICookie public interface ICookie 此接口用于获取 HTTP cookie 的一些信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #!java // 此方法用于获取 Cookie 的域 java.lang.String getDomain() // 此方法用于获取 Cookie 的过期时间 java.util.Date getExpiration() // 此方法用于获取 Cookie 的名称 java.lang.String getName() // 此方法用于获取 Cookie 的路径 java.lang.String getPath() // 此方法用于获取 Cookie 的值 java.lang.String getValue()
IExtensionHelpers public interface IExtensionHelpers 此接口提供了很多常用的辅助方法,扩展可以通过调用 IBurpExtenderCallbacks.getHelpers获得此接口的实例。
开发插件常用的几个方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #!java // 此方法会添加一个新的参数到 HTTP 请求中,并且会适当更新 Content-Length byte[] addParameter(byte[] request, IParameter parameter) // 此方法用于分析 HTTP 请求信息以便获取到多个键的值 IRequestInfo analyzeRequest(byte[] request) // 此方法用于分析 HTTP 响应信息以便获取到多个键的值 IResponseInfo analyzeResponse(byte[] response) // 构建包含给定的 HTTP 头部,消息体的 HTTP 消息 byte[] buildHttpMessage(java.util.List<java.lang.String> headers, byte[] body) // 对给定的 URL 发起 GET 请求 byte[] buildHttpRequest(java.net.URL url) // bytes 到 String 的转换 java.lang.String bytesToString(byte[] data) // String 到 bytes 的转 java.lang.String bytesToString(byte[] data)
IExtensionStateListener public interface IExtensionStateListener 扩展可以实现此接口,然后调用 IBurpExtenderCallbacks.registerExtensionStateListener() 注册一个扩展的状态监听器。在扩展的状态发生改变时,监听器将会收到通知。注意:任何启动后台线程或打开系统资源(如文件或数据库连接)的扩展插件都应该注册一个监听器,并在被卸载后终止线程/关闭资源。
此接口只提供了一个方法:
1 2 #!java void extensionUnloaded()
在插件被 unload (卸载)时,会调用此方法,可以通过重写此方法,在卸载插件时,做一些善后处理工作。
Demo code:
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 #!java package burp; import java.io.PrintWriter; public class BurpExtender implements IBurpExtender, IExtensionStateListener{ private PrintWriter stdout; @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ this.stdout = new PrintWriter(callbacks.getStdout(), true); callbacks.setExtensionName("Her0in"); // 先注册扩展状态监听器 callbacks.registerExtensionStateListener(this); } // 重写 extensionUnloaded 方法 @Override public void extensionUnloaded() { // TODO this.stdout.println("extensionUnloaded ..."); } }
IHttpListener public interface IHttpListener 扩展可以实现此接口。通过调用 IBurpExtenderCallbacks.registerHttpListener() 注册一个 HTTP 监听器。Burp 里的任何一个工具发起 HTTP 请求或收到 HTTP 响应都会通知此监听器。扩展可以得到这些交互的数据,进行分析和修改。
此接口提供了如下方法:
1 2 #!java void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo)
如果在开发插件的时候需要获取到所有的 HTTP 数据包,包括通过 Repeater 工具自定义修改的请求,则必须实现此接口,重写该方法。
参数说明:
1 2 3 4 5 6 7 8 9 #!java // 指示了发起请求或收到响应的 Burp 工具的 ID,所有的 toolFlag 定义在 IBurpExtenderCallbacks 接口中。 int toolFlag // 指示该消息是请求消息(值为True)还是响应消息(值为False) messageIsRequest // 被处理的消息的详细信息,是一个 IHttpRequestResponse 对象 messageInfo
Demo code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #!java package burp; public class BurpExtender implements IBurpExtender, IHttpListener{ @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ callbacks.setExtensionName("Her0in"); callbacks.registerHttpListener(this); } @Override public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) { // TODO here } }
IHttpRequestResponse public interface IHttpRequestResponse 此接口用于检索和更新有关 HTTP 消息的详细信息。
注意:setter 方法通常只能在消息被被处理之前使用,因为它是一个写操作,因此在只读的上下文中也是不可用的。与响应细节相关的 getter 方法只能用在请求发出后使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #!java // 获取用户标注的注释信息 java.lang.String getComment() // 获取用户标注的高亮信息 java.lang.String getHighlight() // 获取请求/响应的 HTTP 服务信息 IHttpService getHttpService() // 获取 HTTP 请求信息 byte[] getRequest() // 获取 HTTP 响应信息 byte[] getResponse() // 更新用户标注的注释信息 void setComment(java.lang.String comment) // 更新用户标注的高亮信息 void setHighlight(java.lang.String color) // 更新 请求/响应的 HTTP 服务信息 void setHttpService(IHttpService httpService) // 更新 HTTP 请求信息 void setRequest(byte[] message) // 更新 HTTP 响应信息 void setResponse(byte[] message)
IHttpRequestResponsePersisted public interface IHttpRequestResponsePersisted extends IHttpRequestResponse 此接口是 IHttpRequestResponse 接口的一个子接口,该接口用于使用 IBurpExtenderCallbacks.saveBuffersToTempFiles() 将一个IHttpRequestResponse 对象的请求和响应消息保存到临时文件。
此接口只提供了一个方法:
1 2 #!java void deleteTempFiles()
注:此方法已经过时了,并且不会执行任何操作。
IHttpRequestResponseWithMarkers public interface IHttpRequestResponseWithMarkers extends IHttpRequestResponse 此接口是 IHttpRequestResponse 接口的一个子接口,此接口用于那些已被标记的 IHttpRequestResponse 对象,扩展可以使用 IBurpExtenderCallbacks.applyMarkers() 创建一个此接口的实例,或提供自己的实现。标记可用于各种情况,如指定Intruder 工具的 payload 位置,Scanner 工具的插入点或将 Scanner 工具的一些问题置为高亮。
此接口提供了两个分别操作请求和响应的方法:
1 2 3 4 5 6 #!java // 获取带有标记的请求信息的详细信息 java.util.List<int[]> getRequestMarkers() // 获取带有标记的请求信息的详细信息 java.util.List<int[]> getResponseMarkers()
这两个方法的返回值均为一个整型数组列表,分别表示请求消息/响应消息标记偏移的索引对。列表中的每一项目都是一个长度为 2 的整型数组(int 2 )包含标记开始和结束的偏移量。如果没有定义请求/响应标记,返回 null。
IHttpService public interface IHttpService 此接口用于提供关于 HTTP 服务信息的细节。
此接口提供了如下方法:
1 2 3 4 5 6 7 8 9 #!java // 返回 HTTP 服务信息的主机名或 IP 地址 java.lang.String getHost() // 返回 HTTP 服务信息的端口 int getPort() // 返回 HTTP 服务信息的协议 java.lang.String getProtocol()
Demo code:
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 #!java package burp; import java.io.PrintWriter; public class BurpExtender implements IBurpExtender, IHttpListener{ private PrintWriter stdout; public IBurpExtenderCallbacks iCallbacks; @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ this.stdout = new PrintWriter(callbacks.getStdout(), true); callbacks.setExtensionName("Her0in"); callbacks.registerHttpListener(this); } @Override public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) { IHttpService iHttpService = messageInfo.getHttpService(); this.stdout.println(iHttpService.getHost()); this.stdout.println(iHttpService.getPort()); this.stdout.println(iHttpService.getProtocol()); } }
IInterceptedProxyMessage public interface IInterceptedProxyMessage 注:在 BurpSuite 的 Proxy 工具下的 Options 标签里有几个自定义消息拦截和响应的功能。读者可以在熟悉了这几个功能后,再了解此接口的作用。
此接口不能被扩展实现,它表示了已被 Burp 代理拦截的 HTTP 消息。扩展可以利用此接口注册一个 IProxyListener 以便接收代理消息的细节。
此接口提供了以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #!java // 获取被拦截的请求消息的客户端 IP 地址 java.net.InetAddress getClientIpAddress() // 获取当前定义的拦截操作类型,具体的类型可以在本接口中看到 int getInterceptAction() // 获取 Burp Proxy 处理拦截消息监听器的名称 java.lang.String getListenerInterface() // 获取被拦截的消息的详细信息 IHttpRequestResponse getMessageInfo() // 获取请求/响应消息的唯一引用号 int getMessageReference() // 设置更新拦截操作 void setInterceptAction(int interceptAction)
Demo code:
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 #!java package burp; import java.io.PrintWriter; public class BurpExtender implements IBurpExtender, IProxyListener{ private PrintWriter stdout; @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ callbacks.setExtensionName("Her0in"); this.stdout = new PrintWriter(callbacks.getStdout(), true); callbacks.registerProxyListener(this); } @Override public void processProxyMessage(boolean messageIsRequest, IInterceptedProxyMessage message) { // 只操作请求消息 if(messageIsRequest){ // 获取并打印出客户端 IP this.stdout.println(message.getClientIpAddress()); // Drop 掉所有请求 message.setInterceptAction(IInterceptedProxyMessage.ACTION_DROP); // TODO here } } }
IIntruderAttack public interface IIntruderAttack 此接口用于操控 Intruder 工具的攻击详情。
此接口提供了以下方法:
1 2 3 4 5 6 #!java // 获取攻击中的 HTTP 服务信息 IHttpService getHttpService() // 获取攻击中的请求模版 byte[] getRequestTemplate()
IIntruderPayloadGenerator public interface IIntruderPayloadGenerator 此接口被用于自定义 Intruder 工具的 payload 生成器。当需要发起一次新的 Intruder 攻击时,扩展需要注册一个 IIntruderPayloadGeneratorFactory 工厂并且必须返回此接口的一个新的实例。此接口会将当前插件注册为一个 Intruder 工具的 payload 生成器。
1 2 3 4 5 6 7 8 9 10 #!java 此接口提供了如下方法: // 此方法由 Burp 调用,用于获取下一个 payload 的值 byte[] getNextPayload(byte[] baseValue) // 此方法由 Burp 调用,用于决定 payload 生成器是否能够提供更多 payload boolean hasMorePayloads() // 此方法由 Burp 调用,用于重置 payload 生成器的状态,这将导致下一次调用 getNextPayload() 方法时会返回第一条 payload void reset()
Demo code:
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 #!java package burp; public class BurpExtender implements IBurpExtender, IIntruderPayloadGeneratorFactory{ @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ callbacks.setExtensionName("Her0in"); // 将当前插件注册为一个 Intruder 工具的 payload 生成器 callbacks.registerIntruderPayloadGeneratorFactory(this); } @Override public String getGeneratorName() { // 设置 payload 生成器名称 return "自定义 payload 生成器"; } @Override public IIntruderPayloadGenerator createNewInstance(IIntruderAttack attack) { // 返回一个新的 payload 生成器的实例 return new IntruderPayloadGenerator(); } // 实现 IIntruderPayloadGenerator 接口,此接口提供的方法是由 Burp 来调用的 class IntruderPayloadGenerator implements IIntruderPayloadGenerator{ @Override public boolean hasMorePayloads() { // TODO here return false; } @Override public byte[] getNextPayload(byte[] baseValue) { // TODO here return null; } @Override public void reset() { // TODO here } } }
在 Burp 加载了上述插件后,可以按照下图标红的步骤操作,即可看到自定义的 payload 生成器:
IIntruderPayloadGeneratorFactory public interface IIntruderPayloadGeneratorFactory 扩展可以实现此接口,并且可以调用 IBurpExtenderCallbacks.registerIntruderPayloadGeneratorFactory() 注册一个自定义的 Intruder 工具的 payload 生成器。
该接口提供了以下方法:
1 2 3 4 5 6 7 #!java // 此方法由 Burp 调用,用于创建一个 payload 生成器的新实例。当用户发动一次 Intruder 攻击时,将会使用该方法返回的 payload 生成器的实例 IIntruderPayloadGenerator createNewInstance(IIntruderAttack attack) // 此方法由 Burp 调用,用于获取 payload 生成器的名称 java.lang.String getGeneratorName()
IIntruderPayloadProcessor public interface IIntruderPayloadProcessor 扩展可以实现此接口,并且可以调用 IBurpExtenderCallbacks.registerIntruderPayloadProcessor() 注册一个自定义 Intruder 工具的 payload 的处理器。此接口会将当前插件注册为一个 Intruder 工具的 payload 处理器。
该接口提供了以下方法:
1 2 3 4 5 6 7 8 #!java // 此方法由 Burp 调用,用于获取 payload 处理器的名称 java.lang.String getProcessorName() // 此方法由 Burp 调用,当处理器每次应用 payload 到一次 Intruder 攻击时,Burp 都会调用一次此方法 byte[] processPayload(byte[] currentPayload, byte[] originalPayload, byte[] baseValue) // processPayload 方法说明:
参数说明:
currentPayload - 当前已被处理过的 payload 的值
originalPayload - 在应用处理规则之前的 payload 的原始值
baseValue - payload 位置的基准值,将用当前已被处理过的 payload 替代
返回值:返回已被处理过的 payload 的值。 如果返回 null 意味着当前的 payload 将被跳过,并且此次攻击将被直接移动到下一个 payload 。
Demo code:
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 #!java package burp; public class BurpExtender implements IBurpExtender, IIntruderPayloadProcessor{ @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ callbacks.setExtensionName("Her0in"); // 将当前插件注册为一个 Intruder 工具的 payload 处理器 callbacks.registerIntruderPayloadProcessor(this); } // 此方法由 Burp 调用 @Override public String getProcessorName() { // 设置自定义 payload 处理器的名称 return "自定义 payload 处理器"; } // 此方法由 Burp 调用,且会在每次使用一个 payload 发动攻击时都会调用一次此方法 @Override public byte[] processPayload(byte[] currentPayload, byte[] originalPayload, byte[] baseValue) { // TODO here return null; } }
在 Burp 加载了上述插件后,可以按照下图标红的步骤操作,即可看到自定义的 payload 生成器:
IMenuItemHandler public interface IMenuItemHandler 此接口已过时,不推荐再使用,请使用IContextMenuFactory代替。
扩展可以实现此接口,并且通过调用 IBurpExtenderCallbacks.registerMenuItem() 方法注册一个自定义的上下文菜单项。
此接口提供了如下方法:
1 2 3 #!java // 当用户单击一个已经在 Burp 中注册过的上下文菜单项时 Burp 会调用一次此方法。不过,此方法已经过时 void menuItemClicked(java.lang.String menuItemCaption, IHttpRequestResponse[] messageInfo)
IMessageEditor public interface IMessageEditor 此接口被用于使用 Burp 的 HTTP 消息编辑框的实例提供扩展功能,以便扩展插件可以在它自己的 UI 中使用消息编辑框,扩展插件可以通过调用 IBurpExtenderCallbacks.createMessageEditor() 获得此接口的实例。
此接口提供了以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #!java // 此方法返回了编辑器的 UI 组件,扩展插件可以将其添加到自己的 UI 中 java.awt.Component getComponent() // 此方法用于获取当前已显示的消息,此消息可能已被用户修改 byte[] getMessage() // 此方法返回了用户当前所选择的数据 byte[] getSelectedData() // 此方法用于决定当前的消息是否可被用户修改 boolean isMessageModified() // 此方法用于将一个 HTTP 消息显示在编辑器中 void setMessage(byte[] message, boolean isRequest)
注: 此接口需要与 IMessageEditorTabFactory 等相关接口一起使用。
Demo code:
1 请见 IMessageEditorTabFactory 的实例代码。
IMessageEditorController public interface IMessageEditorController 此接口被用于 IMessageEditor 获取当前显示的消息的细节。创建了 Burp 的 HTTP 消息编辑器实例的扩展插件可以有选择的实现 IMessageEditorController 接口,当扩展插件需要当前消息的其他信息时,编辑器将会调用此接口(例如:发送当前消息到其他的 Burp 工具中)。扩展通过 IMessageEditorTabFactory 工厂提供自定义的编辑器标签页,此工厂的 createNewInstance 方法接受一个由该工厂所生成的每一个标签页的 IMessageEditorController 对象的引用,当标签页需要当前消息的其他信息时,则会调用该对象。
此方法提供了以下方法:
1 2 3 4 5 6 7 8 9 #!java // 此方法用于获取当前消息的 HTTP 服务信息 IHttpService getHttpService() // 此方法用于获取当前消息的 HTTP 请求(也有可能是一个响应消息) byte[] getRequest() // 此方法用于获取当前消息的 HTTP 响应(也有可能是一个请求消息) byte[] getResponse()
Demo code:
1 请见 IMessageEditorTabFactory 的实例代码。
IMessageEditorTab public interface IMessageEditorTab 扩展插件通过注册 IMessageEditorTabFactory 工厂,此工厂的 createNewInstance 返回一个当前接口的实例,Burp 将会在其 HTTP 消息编辑器中创建自定义的标签页。
此接口提供了如下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #!java // 此方法返回当前显示的消息 byte[] getMessage() // 此方法用于获取当前已被用户选择的数据 byte[] getSelectedData() // 此方法返回自定义标签页的标题 java.lang.String getTabCaption() // 此方法返回自定义标签页内容的组件 java.awt.Component getUiComponent() // 此方法用于指示在显示一个新的 HTTP 消息时,是否启用自定义的标签页 boolean isEnabled(byte[] content, boolean isRequest) // 此方法用于决定当前显示的消息是否可被用户修改 boolean isModified() // 此方法可以显示一个新的消息或者清空已存在的消息 void setMessage(byte[] content, boolean isRequest)
Demo code:
1 请见 IMessageEditorTabFactory 的实例代码。
IMessageEditorTabFactory public interface IMessageEditorTabFactory 扩展可以实现此接口,并且可以调用 IBurpExtenderCallbacks.registerMessageEditorTabFactory() 注册一个自定义的消息编辑器标签页的工厂。扩展插件可以在 Burp 的 HTTP 编辑器中渲染或编辑 HTTP 消息。
此接口提供了一个方法:
1 2 3 #!java // Burp 将会对每一个 HTTP 消息编辑器调用一次此方法,此工厂必须返回一个新的 IMessageEditorTab 对象 IMessageEditorTab createNewInstance(IMessageEditorController controller, boolean editable)
Demo code:
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 #!java package burp; import java.awt.Component; import java.io.PrintWriter; public class BurpExtender implements IBurpExtender, IMessageEditorTabFactory{ public PrintWriter stdout; public IExtensionHelpers helpers; private IBurpExtenderCallbacks callbacks; @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ this.stdout = new PrintWriter(callbacks.getStdout(), true); this.callbacks = callbacks; this.helpers = callbacks.getHelpers(); callbacks.setExtensionName("Her0in"); callbacks.registerMessageEditorTabFactory(this); } @Override public IMessageEditorTab createNewInstance( IMessageEditorController controller, boolean editable) { // 返回 IMessageEditorTab 的实例 return new iMessageEditorTab(); } class iMessageEditorTab implements IMessageEditorTab{ // 创建一个新的文本编辑器 private ITextEditor iTextEditor = callbacks.createTextEditor(); @Override public String getTabCaption() { // 设置消息编辑器标签页的标题 return "测试 MessageEditorTab"; } @Override public Component getUiComponent() { // 返回 iTextEditor 的组件信息,当然也可以放置其他的组件 return iTextEditor.getComponent(); } @Override public boolean isEnabled(byte[] content, boolean isRequest) { // 在显示一个新的 HTTP 消息时,启用自定义的标签页 // 通过 content 和 isRequest 也可以对特定的消息进行设置 return true; } @Override public void setMessage(byte[] content, boolean isRequest) { // 把请求消息里面的 data 参数进行 Base64 编码操作 // 这里并未处理参数中没有 data 时的异常 IParameter parameter = helpers.getRequestParameter(content, "data"); stdout.println("data = " + parameter.getValue()); iTextEditor.setText(helpers.stringToBytes(helpers.base64Encode(parameter.getValue()))); } @Override public byte[] getMessage() { // 获取 iTextEditor 的文本 return iTextEditor.getText(); } @Override public boolean isModified() { // 允许用户修改当前的消息 return true; } @Override public byte[] getSelectedData() { // 直接返回 iTextEditor 中选中的文本 return iTextEditor.getSelectedText(); } } }
加载上述代码生成的插件后,会显示自定义的标签页和文本编辑器。
注意:官网提供的自定义消息编辑器的代码有误!
IParameter public interface IParameter 此接口用于操控 HTTP 请求参数,开发者通过此接口可以灵活的获取请求或响应里的参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #!java // 此方法用于获取参数名称 java.lang.String getName() // 此方法用于获取在 HTTP 请求里面的最后一个参数的名称 int getNameEnd() // 此方法用于获取在 HTTP 请求里面的第一个参数的名称 int getNameStart() // 此方法用于获取参数类型,参数的类型在 IParameter 接口中有定义 byte getType() // 此方法用于获取参数的值 java.lang.String getValue() // 此方法用于获取最后一个参数的值 int getValueEnd() // 此方法用于获取第一个参数的值 int getValueStart()
Demo code:
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 #!java package burp; import java.io.PrintWriter; import java.util.List; public class BurpExtender implements IBurpExtender, IHttpListener{ public PrintWriter stdout; public IExtensionHelpers helpers; private IBurpExtenderCallbacks callbacks; @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ this.stdout = new PrintWriter(callbacks.getStdout(), true); this.callbacks = callbacks; this.helpers = callbacks.getHelpers(); callbacks.setExtensionName("Her0in"); callbacks.registerHttpListener(this); } @Override public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) { // 获取请求中的参数 if(messageIsRequest){ IRequestInfo iRequestInfo = helpers.analyzeRequest(messageInfo); // 获取请求中的所有参数 List<IParameter> iParameters = iRequestInfo.getParameters(); for (IParameter iParameter : iParameters) { if(iParameter.getType() == IParameter.PARAM_URL) stdout.println("参数:" + iParameter.getName() + " 在 URL中"); stdout.println("参数:" + iParameter.getName() + " 的值为:" + iParameter.getValue()); } } } }
加载上述代码生成的插件后,执行效果如下图所示:
IProxyListener public interface IProxyListener 扩展可以实现此接口,并且可以通过调用 IBurpExtenderCallbacks.registerProxyListener()注册一个代理监听器。在代理工具处理了请求或响应后会通知此监听器。扩展插件通过注册这样一个监听器,对这些消息执行自定义的分析或修改操作。
此接口提供了一个很常用的方法:
1 2 3 #!java void processProxyMessage(boolean messageIsRequest, IInterceptedProxyMessage message)
Demo code:
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 #!java package burp; import java.io.PrintWriter; public class BurpExtender implements IBurpExtender, IProxyListener{ public PrintWriter stdout; public IExtensionHelpers helpers; private IBurpExtenderCallbacks callbacks; @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ this.stdout = new PrintWriter(callbacks.getStdout(), true); this.callbacks = callbacks; this.helpers = callbacks.getHelpers(); callbacks.setExtensionName("Her0in"); callbacks.registerProxyListener(this); } @Override public void processProxyMessage(boolean messageIsRequest, IInterceptedProxyMessage message) { // TODO here } }
IRequestInfo public interface IRequestInfo 此接口被用于获取一个 HTTP 请求的详细信息。扩展插件可以通过调用 IExtensionHelpers.analyzeRequest() 获得一个 IRequestInfo 对象。
此接口提供了以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #!java // 此方法用于获取 HTTP body 在请求消息中的起始偏移量 int getBodyOffset() // 此方法用于获取请求消息的 HTTP 类型 byte getContentType() // 此方法用于获取请求中包含的 HTTP 头 java.util.List<java.lang.String> getHeaders() // 此方法用于获取请求的 HTTP 方法 java.lang.String getMethod() // 此方法用于获取请求中包含的参数 java.util.List<IParameter> getParameters() // 此方法用于获取请求中的 URL java.net.URL getUrl()
Demo code:
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 #!java package burp; import java.io.PrintWriter; public class BurpExtender implements IBurpExtender , IHttpListener { public PrintWriter stdout ; public IExtensionHelpers helpers; @Override public void registerExtenderCallbacks (final IBurpExtenderCallbacks callbacks) { this .stdout = new PrintWriter(callbacks.getStdout(), true ); this .helpers = callbacks.getHelpers(); callbacks.setExtensionName("Her0in" ); callbacks.registerHttpListener(this ); } @Override public void processHttpMessage (int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) { if (messageIsRequest){ stdout .println(helpers.bytesToString(messageInfo.getRequest())); } else { IResponseInfo responseInfo = helpers.analyzeResponse(messageInfo.getResponse()); short statusCode = responseInfo.getStatusCode(); stdout .printf ("响应码 => %d\r\n" , statusCode); } } }
加载上述代码生成的插件后,执行效果如下图所示:
IResponseInfo public interface IResponseInfo 此接口被用于获取一个 HTTP 请求的详细信息。扩展插件可以通过调用 IExtensionHelpers. analyzeResponse() 获得一个 IResponseInfo 对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #!java // 此方法用于获取 HTTP body 在响应消息中的起始偏移量 int getBodyOffset() // 此方法用于获取响应消息中设置的 HTTP Cookie java.util.List<ICookie> getCookies() // 此方法用于获取包含在响应消息中的 HTTP 头 java.util.List<java.lang.String> getHeaders() // 此方法用于获取根据 HTTP 响应判断出的 MIME 类型 java.lang.String getInferredMimeType() // 此方法用于获取 HTTP 响应头中指示的 MIME 类型 java.lang.String getStatedMimeType() // 此方法用于获取 HTTP 状态码 short getStatusCode()
Demo code:
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 #!java package burp; import java.io.PrintWriter; public class BurpExtender implements IBurpExtender , IHttpListener { public PrintWriter stdout ; public IExtensionHelpers helpers; @Override public void registerExtenderCallbacks (final IBurpExtenderCallbacks callbacks) { this .stdout = new PrintWriter(callbacks.getStdout(), true ); this .helpers = callbacks.getHelpers(); callbacks.setExtensionName("Her0in" ); callbacks.registerHttpListener(this ); } @Override public void processHttpMessage (int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) { if (messageIsRequest){ stdout .println(helpers.bytesToString(messageInfo.getRequest())); } else { IResponseInfo responseInfo = helpers.analyzeResponse(messageInfo.getResponse()); short statusCode = responseInfo.getStatusCode(); stdout .printf ("响应码 => %d\r\n" , statusCode); } } }
IScanIssue public interface IScanIssue 此接口用于获取 Scanner 工具扫描到的问题的细节。扩展可以通过注册一个 IScannerListener或者是 通过调用 IBurpExtenderCallbacks.getScanIssues() 获取扫描问题的细节。扩展同样可以通过注册 IScannerCheck 接口或者是调用 IBurpExtenderCallbacks.addScanIssue() 方法来自定义扫描问题,此时扩展需要提供它对此接口的实现。
此接口提供了以下方法:
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 #!java // 此方法返回扫描问题的信任等级 java.lang.String getConfidence() // 此方法返回生成扫描问题所对应的 HTTP 消息 IHttpRequestResponse[] getHttpMessages() // 此方法返回生成扫描问题所对应的 HTTP 服务信息 IHttpService getHttpService() // 此方法返回指定扫描问题类型的背景描述信息 java.lang.String getIssueBackground() // 此方法返回指定的扫描问题的详细信息 java.lang.String getIssueDetail() // 此方法返回扫描问题类型的名称 java.lang.String getIssueName() // 此方法返回扫描问题类型的数字标志符 int getIssueType() // 此方法返回指定扫描问题的解决方式的背景描述信息 java.lang.String getRemediationBackground() // 此方法返回指定扫描问题的解决方式的背景详情 java.lang.String getRemediationDetail() // 此方法返回扫描问题的错误等级 java.lang.String getSeverity() // 此方法返回生成扫描问题对应的 URL 信息 java.net.URL getUrl()
Demo code:
1 请见 IScannerListener 的实例代码。
IScannerCheck public interface IScannerCheck 扩展可以实现此接口,之后可以通过调用 IBurpExtenderCallbacks.registerScannerCheck()注册一个自定义的 Scanner 工具的检查器。Burp 将会告知检查器执行“主动扫描”或“被动扫描”,并且在确认扫描到问题时给出报告。
1 2 3 4 5 6 7 8 9 #!java // 当自定义的Scanner工具的检查器针对同一个 URL 路径报告了多个扫描问题时,Scanner 工具会调用此方法 int consolidateDuplicateIssues(IScanIssue existingIssue, IScanIssue newIssue) // Scanner 工具会对每一个可插入的点执行“主动扫描” java.util.List<IScanIssue> doActiveScan(IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) // Scanner 工具会对每一个可插入的点执行“被动扫描” java.util.List<IScanIssue> doPassiveScan(IHttpRequestResponse baseRequestResponse)
Demo code:
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 #!java package burp; import java.io.PrintWriter; import java.util.List; public class BurpExtender implements IBurpExtender, IScannerCheck{ public PrintWriter stdout; public IExtensionHelpers helpers; @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ this.stdout = new PrintWriter(callbacks.getStdout(), true); this.helpers = callbacks.getHelpers(); callbacks.setExtensionName("Her0in"); callbacks.registerScannerCheck(this); } @Override public List<IScanIssue> doPassiveScan( IHttpRequestResponse baseRequestResponse) { // TODO here return null; } @Override public List<IScanIssue> doActiveScan( IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) { // TODO here return null; } @Override public int consolidateDuplicateIssues(IScanIssue existingIssue, IScanIssue newIssue) { // TODO here return 0; } }
IScannerInsertionPoint public interface IScannerInsertionPoint 此接口被用于定义一个用于Scanner工具检查器扫描的插入点。扩展可以通过注册 IScannerCheck 获得此接口实例,或者通过注册 IScannerInsertionPointProvider 创建一个 Burp 所使用的扫描检查器实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #!java // 此方法用于使用指定的 payload 在插入点构建一个请求 byte[] buildRequest(byte[] payload) // 此方法返回插入点的基本值 java.lang.String getBaseValue() // 此方法返回插入点的名称 java.lang.String getInsertionPointName() // 此方法返回插入点的类型,插入点类型在IScannerInsertionPoint接口中定义 byte getInsertionPointType() // 当使用指定的 payload 替换到插入点时,此方法可以决定 payload 在请求中的偏移量 int[] getPayloadOffsets(byte[] payload)
Demo code:
IScannerInsertionPointProvider public interface IScannerInsertionPointProvider 扩展可以实现此接口并且可以通过调用 IBurpExtenderCallbacks.registerScannerInsertionPointProvider() 注册自定义扫描插入点的工厂。
此接口提供了以下方法:
1 2 3 java.util.List <IScannerInsertionPoint> getInsertionPoints(IHttpRequestResponse baseRequestResponse)
IScannerListener public interface IScannerListener 扩展可以实现此接口,并且可以通过调用 IBurpExtenderCallbacks.registerScannerListener() 注册一个 Scanner 工具的监听器。当 Scanner 工具扫描到新的问题时,会通知此监听器。扩展通过注册这样的监听器用于针对扫描问题自定义的分析和记录。
此接口提供了以下方法:
1 2 3 #!java void newScanIssue(IScanIssue issue)
Demo code:
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 #!java package burp; import java.io.PrintWriter; public class BurpExtender implements IBurpExtender , IScannerListener { public PrintWriter stdout ; public IExtensionHelpers helpers; @Override public void registerExtenderCallbacks (final IBurpExtenderCallbacks callbacks) { this .stdout = new PrintWriter(callbacks.getStdout(), true ); this .helpers = callbacks.getHelpers(); callbacks.setExtensionName("Her0in" ); callbacks.registerScannerListener(this ); } @Override public void newScanIssue (IScanIssue issue) { stdout .println("扫描到新的问题 :" ); stdout .println("url => " + issue.getUrl()); stdout .println("详情 => " + issue.getIssueDetail()); } }
加载上述代码生成的插件后,执行效果如下图所示:
IScanQueueItem public interface IScanQueueItem 此接口被用于获取在 Burp 的 Scanner 工具中激活的扫描队列里的项目详情。扩展可以通过调用 IBurpExtenderCallbacks.doActiveScan() 获得扫描队列项目的引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #!java // 此方法可以取消扫描队列项目中的扫描状态 void cancel() // 获取扫描队列项目生成的问题的细节 IScanIssue[] getIssues() // 此方法返回扫描队列项目发生错误时的网络错误号 int getNumErrors() // 此方法返回扫描队列项目的攻击插入点的数量 int getNumInsertionPoints() // 此方法返回扫描队列项目已经发出的请求的数量 int getNumRequests() // 此方法返回扫描队列项目中已经完成扫描的百分比 byte getPercentageComplete() // 此方法返回扫描队列项目的状态描述 java.lang.String getStatus()
IScopeChangeListener public interface IScopeChangeListener 扩展可以实现此接口并且可以通过调用 IBurpExtenderCallbacks.registerScopeChangeListener() 注册一个 Target 工具下的 scope 变化监听器。当 Burp 的 Target 工具下的 scope 发生变化时,将会通知此接口。
此接口提供了以下方法:
1 2 3 #!java void scopeChanged()
Demo code:
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 #!java package burp; import java.io.PrintWriter; public class BurpExtender implements IBurpExtender, IScopeChangeListener{ public PrintWriter stdout; public IExtensionHelpers helpers; @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ this.stdout = new PrintWriter(callbacks.getStdout(), true); this.helpers = callbacks.getHelpers(); callbacks.setExtensionName("Her0in"); callbacks.registerScopeChangeListener(this); } @Override public void scopeChanged() { // 手动添加或右键菜单添加目标到 scope 列表,就会执行此方法 stdout.println("scope 有变化!"); } }
加载上述代码生成的插件后,执行效果如下图所示:
ISessionHandlingAction public interface ISessionHandlingAction 扩展可以实现此方法并且可以通过调用 IBurpExtenderCallbacks.registerSessionHandlingAction() 注册一个自定义的会话操作动作。每一个已注册的会话操作动作在会话操作规则的UI中都是可用的,并且用户可以选择其中一个作为会话操作行为的规则。用户可以选择直接调用操作,也可以按照宏定义调用操作。
此接口调用了如下方法:
1 2 3 4 5 6 #!java // 此方法由 Burp 调用获取会话操作行为的名称 java.lang.String getActionName() // 当会话操作行为被执行时会调用此方法 void performAction(IHttpRequestResponse currentRequest, IHttpRequestResponse[] macroItems)
ITab public interface ITab 此接口用于自定义的标签页,调用 IBurpExtenderCallbacks.addSuiteTab() 方法可以在 Burp 的 UI 中显示自定义的标签页。
1 2 3 4 5 6 #!java // 此方法用于获取自定义标签的标题文本 java.lang.String getTabCaption() // Burp 调用此方法获取自定义标签页显示的组件 java.awt.Component getUiComponent()
Demo code:
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 54 #!java package burp; import java.awt.Component; import java.io.PrintWriter; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class BurpExtender implements IBurpExtender, ITab{ public PrintWriter stdout; public IExtensionHelpers helpers; private JPanel jPanel1; private JButton jButton1; @Override public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ this.stdout = new PrintWriter(callbacks.getStdout(), true); this.helpers = callbacks.getHelpers(); callbacks.setExtensionName("Her0in"); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { //创建一个 JPanel jPanel1 = new JPanel(); jButton1 = new JButton("点我"); // 将按钮添加到面板中 jPanel1.add(jButton1); //自定义的 UI 组件 callbacks.customizeUiComponent(jPanel1); //将自定义的标签页添加到Burp UI 中 callbacks.addSuiteTab(BurpExtender.this); } }); } @Override public String getTabCaption() { // 返回自定义标签页的标题 return "Her0in"; } @Override public Component getUiComponent() { // 返回自定义标签页中的面板的组件对象 return jPanel1; } }
加载上述代码生成的插件后,执行效果如下图所示:
ITempFile public interface ITempFile 此接口用于操作调用 IBurpExtenderCallbacks.saveToTempFile() 创建的临时文件。
1 2 3 4 5 6 #!java // 删除临时文件,此方法已过时 void delete() // 此方法用于获取临时文件内容的缓冲区 byte[] getBuffer()
ITextEditor public interface ITextEditor 此接口用于扩展 Burp 的 原始文本编辑器,扩展通过调用 IBurpExtenderCallbacks.createTextEditor() 获得一个此接口的实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #!java // 此方法返回用于扩展添加自定义的编辑器的 UI 组件 java.awt.Component getComponent() // 此方法用于获取当前的已选择的文本 byte[] getSelectedText() // 此方法用于获取用户在已显示的文本中选择的边界 int[] getSelectionBounds() // 此方法用于获取当前已显示的文本 byte[] getText() // 此方法用于指示用户是否对编辑器的内容做了修改 boolean isTextModified() // 此方法用于决定当前的编辑器是否可编辑 void setEditable(boolean editable) // 此方法用于更新编辑器下边的搜索框的搜索表达式 void setSearchExpression(java.lang.String expression) // 此方法用于更新编辑器中当前已显示的文本 void setText(byte[] text)
Demo code:
1 请见 IMessageEditorTabFactory 的实例代码。
转自:https://www.tuicool.com/articles/aaaa6fA