使扩展运行的基本步骤

在介绍每种语言的细节之前,需要记住一些通用的上下文:Burp查找一个名为BurpExtender的类以实例化(没有构造函数参数),然后在此对象上调用registerExtenderCallbacks()并传递一个“回调”对象 。 将此视为扩展的入口点,使您可以告诉Burp扩展的功能以及Burp何时询问扩展问题。

首先,您需要一个IDE。 一些流行的选项是:IntelliJ IDEA,Netbeans和Eclipse。

创建一个新项目,并创建一个名为burp的包。接下来需要复制接口文件,这些文件可以在Extender / APIs / Save接口文件中从Burp导出。将接口文件保存到为burp包创建的文件夹中。

现在,您已经设置了常规环境,您将需要创建实际的扩展文件。 创建一个名为BurpExtender.java的新文件(或者,如果您的IDE为您创建文件,则创建一个名为BurpExtender的新类)并粘贴以下代码:

package burp;
public class BurpExtender implements IBurpExtender
{public void registerExtenderCallbacks (IBurpExtenderCallbacks callbacks){
// your extension code here}
}

该示例完全不执行任何操作,但是可以编译,并且可以在从IDE生成JAR文件后将其加载到Burp中-该文件通常位于build或dist目录中。 在Burp中,转到“扩展器”工具和“扩展”选项卡,然后添加新的扩展。选择扩展名类型Java,然后指定JAR文件的位置。 这应该没有错误地加载到Burp中。

Burp依靠Jython提供其Python支持。 您将需要下载Standalone Jar; 版本并配置Burp及其位置(在Extender / Options / Python环境中)。

现在,以您喜欢的任何名称创建一个新文件,以“ .py”结尾,然后将以下内容添加到该文件中:

from burp import IBurpExtender
class BurpExtender(IBurpExtender):def registerExtenderCallbacks( self, callbacks):# 您的扩展代码在这里
返回

然后转到扩展选项卡,并添加一个新的扩展。 选择扩展名类型Python,然后指定文件的位置。

这个示例什么也不做,但是应该没有任何错误地加载到Burp中。

注意:由于Jython动态生成Java类的方式,如果加载多个不同的Python扩展,或者多次卸载并重新加载Python扩展,则可能会遇到内存问题。 如果发生这种情况,您将看到类似以下的错误:

java.lang.OutOfMemoryError: PermGen space

通过配置低于8的Java版本来分配更多的PermGen存储,可以通过在启动Burp时向命令行添加XX:MaxPermSize选项来避免此问题。 例如:

java -XX:MaxPermSize=1G -jar burp.jar

该选项在Java 8+中不可用,并且应该由JVM自动管理permgen大小。

Burp依靠JRuby提供其Ruby支持。 您将需要下载Complete .jar版本,并使用其位置(在Extender / Options / Ruby环境中)配置Burp。

现在,以您喜欢的任何名称创建一个新文件,以“ .rb”结尾,然后将以下内容添加到该文件中:

require 'java'
java_import 'burp.IBurpExtender'

class BurpExtenderinclude IBurpExtender

def registerExtenderCallbacks(callbacks)# 您的扩展代码在这里结束
结束

然后转到扩展选项卡,并添加一个新的扩展。 选择扩展名类型Ruby,然后指定文件的位置。

这个示例什么也不做,但是应该没有任何错误地加载到Burp中。

有用的API

关于Burp的编程扩展要注意的第一件重要事情是,在大多数情况下,将要检查的数据以字节数组(byte [])的形式提供,如果您通常使用字符串编程的话,可能需要一些时间来适应它。重要的是要理解,尽管可以从字节转换为字符串,但此过程并非完全无关紧要,并且可能会使扩展程序的内存使用量增加。 在某些情况下,这是不可避免的(例如,您需要针对请求/响应执行正则表达式),但总的来说,您应该尝试直接使用字节。

Burp将为您提供各种数据对象,这些对象将对HTTP请求、响应、参数、cookie等以及特定于Burp的项目(例如问题)进行建模。 我们将在您熟悉HTTP并将Burp作为工具的假设下讨论许多这样的模型。

假设您已经在上面创建了空白扩展的起点,因为您已经实现了IBurpExtender接口,则扩展的入口将是以下方法:

void registerExtenderCallbacks (IBurpExtenderCallbacks callbacks);

旁注:由于通过Java字节码的转换层提供了Python和Ruby的兼容性,因此我们将在最严格的意义上讨论所有接口。 要将它们读取为Python或Ruby函数,只需删除类型即可。 例如 在Python中:

def registerExtenderCallbacks self, callbacks)

或在Ruby中:

def registerExtenderCallbacks(callbacks)

使用Java定义可以使我们尽可能精确,并可以在有用的地方讨论转换层的细节。 为了清楚起见,本文档中提到的某些方法名称已使用接口名称进一步限定。

您可以用callbacks对象做的第一件有用的事情是告诉Burp你的扩展被调用了什么:

callbacks.setExtensionName (您的扩展名);

这使用户可以看到您的扩展名。

您可能要做的第一件事是获得帮助者的副本,以使您的生活更轻松:

IExtensionHelpers helpers = callbacks.getHelpers();

首先检查出的工具是你的字节实用程序:

int indexOf (byte[] data, byte[] pattern, boolean caseSensitive, int from, int to);
String bytesToString(byte[] data);
byte[] stringToBytes(String data);
String urlDecode(String data);
String urlEncode(String data);
byte[] urlDecode(byte[] data);
byte[] urlEncode(byte[] data);
byte[] base64Decode(String data);
byte[] base64Decode(byte[] data);
String base64Encode(String data);
String base64Encode(byte[] data);

这些允许您在需要时在字符串和字节之间进行转换,并为您提供有用的编码,可用于处理web上的数据。

Burp的扩展程序API除了字节以外还向您返回了一些数据类型,以方便的方式对HTTP概念进行建模。 简而言之,这些就是IHttpRequestResponse,它使您可以访问IHttpService(即域,端口和协议)并包装请求和响应。 可以通过IExtensionHelpers.analyzeRequest()的各种重载来进一步处理请求和响应,以便您检查参数、cookie等。

编写扩展的核心部分是告诉Burp您的扩展能够处理什么,这通过向Burp注册代码位的机制起作用,以便Burp可以在以后执行该代码。 我们不会介绍IExtenderCallbacks对象提供的所有功能。 最好浏览源代码,以了解Burp理解的可能功能,但作为示例,您可以通过以下API注册一个对象(可能是当前的对象(在Java中),也可以是self(在Python / Ruby中):

void IBurpExtenderCallbacks.registerExtensionStateListener(IExtensionStateListener listener);

e.g.

callbacks.registerExtensionStateListener(this);

现在,为了了解成为IExtensionStateListener的含义,您应该看一下该API的源代码,这非常简单,因为只有一种方法可以实现:

void IExtensionStateListener.extensionUnloaded();

因此,您可以确定用户何时卸载扩展程序,Burp会通知您此信息(如果您已注册!),以便您进行一些清理,例如关闭数据库连接。这通常被称为事件驱动的体系结构,并且在您知道某些事件可能发生但不知道确切时间的情况下很常见。 注册机制使您可以选择要处理的内容,从而可以集中精力进行工作。

通常,您可能想要保存一些状态; 也许您已经要求用户进行配置,或者只是发现了以后要使用的功能。 最简单的方法是使用以下API:

void IBurpExtenderCallbacks.saveExtensionSetting(字符串名称,字符串值);
String IBurpExtenderCallbacks.loadExtensionSetting(字符串名称);

这些API存在且有用的原因是,它们避免了自己管理文件或数据库的复杂性。 为了简单地保存和重新加载数据,您应该始终喜欢使用这些机制,而不要引起文件系统、权限和跨操作系统差异的麻烦。

另一个可帮助您避免管理文件的API是:

ITempFile IBurpExtenderCallbacks.saveToTempFile(byte[] buffer);
byte[] ITempFile.getBuffer();

如果您要处理大量数据并且不希望消耗过多的内存,这很有用。 请注意,不建议使用ITempFile.delete()。 临时文件会在关闭时由Burp自动删除。

关于在Python和Ruby中处理Java数组的特别说明

如前所述,Python和Ruby的兼容性是通过转换层实现的,该实现细节有时会泄漏出去。 您将在处理Java数组时注意到这一点,而在处理字节时则最为常见。

创建一个字节兼容的对象以传递给Burp Extender API:

bytearray("foo") # => new byte[] {'f', 'o', 'o'}

要将现有列表转换为Java数组:

from jarray import array
array([1, 2, 3], 'i') ># => new int[] {1, 2, 3}

注意对应于“整数”的“ i”。 可以在Jython文档中找到各种原始类型名称。

创建一个字节兼容的对象以传递给Burp Extender API:

"foo".bytes.to_a # => new byte[] {'f', 'o', 'o'}

要将现有数组转换为Java数组:

[1, 2, 3].to_java :int # => new int[] {1, 2, 3}

注意对应于整数的int。 各种原始类型名称可以在JRuby文档中找到。

更多示例

某些Burp API已在官方可扩展性页面底部的示例扩展中突出显示,其源代码包含解释该代码的注释,从而为在实际设置中学习各种可用的API提供了丰富的资源。

Burp 社区

有关Burp扩展的更多帮助和示例,您可以参考技术支持中心中的Burp Extensions社区讨论。

Get more help