Posted on 2nd February 2018 by Paul Ritchie


In a recent blog post [1] I showed how to get Netbeans GUI designer into your Burp Extender building. Not doing so leaves you pretty much designing Java SWING GUIs by hand which usually leads to minimal interfaces. In this blog post I have taken the dip and made an Extender publicly available which does something.

What does BurpExtenderForge do?

It allows you to make Python based Extenders within Burp itself. I found myself needing a simple custom payload encoder and wanting to do that without going outside Burp. Sure the workflow isn't too bad with an external Python editor but why not keep your world light where you can?

Shown below is a screenshot of the interface:

BurpExtenderForge Interface
Figure 1 - BurpExtenderForge User Interface

It has two functions as described below:

  1. Execute Python - as illustrated above you have a functional Python interpreter and access to the STDOUT and STDERR messages under the "Output Text" label.
  2. Create Simple Extenders and Enable Them - the three tabs to the right are sample Python Extenders heavily based on PortSwigger's own examples at reference [2]. Set your code changes and hit "Enable Temporarily". This will hackily attempt to setup your new Extender within Burp.
I say "hackily" because there is no real API available to have one Extender register another Extender. It is clearly a fairly meta thing to be doing! So I suggest you use the "Enable Temporarily" while developing only. Use the "Save" button to save your Extender as a ".py" file, then use the "Extender" -> "Extensions" -> "Add" flow pemanent use.

How Do you Install It?

I will attempt to get it directly into the Burp App store soon but until then you have some steps.

SecarmaLab's Github Repository [3] has the source code and distribution ".jar" file in there. If you try to install ExtenderForge by simply loading the "BurpExtenderForge.jar" as a Java Extender you would see the error shown below:


Figure 2 - NoClassDefFoundError

This is because you have not setup the Classpath within Burp. ExtenderForge relies on the following two external Libraries:

Many Extenders for Burp are written in Python. If you have already installed one of those then you will already have Jython configured. To check if that is the case, within Burp go to "Extender" -> "Options" and then check the "Python Environment" settings as shown below:

Figure 3 - Python Environment Settings

If you have no settings for Jython's standalone JAR then you will need to set that up. ExtenderForge's "/lib" folder contains a version of the Jython Jar which is tested as working. You can point directly to that but I would recommend you move the standalone JAR to a predictable location that works for you. 

To remove the "NoClassDefFoundError" we also need to place "JSyntaxPane" into a useful location. Burp allows you to configure one folder in which it will look for all .jar libraries for all of your Extenders. I would suggest you create a new folder that you are comfortable with and then move the "jsyntaxpane-1.0.0.jar" from ExtenderForge's "/lib" folder into that location. As this folder is global to all Extenders you should get into the habit of moving all libraries into a central folder. 

To tell Burp where your library files are, go to "Extender" -> "Options" and then set the "Java Environment" options shown below:

Figure 4 - Java Environment Settings

Select the folder you moved "jsyntaxpane-1.0.0.jar" into and you will be good to go.

Example Usage

The first Extender I made was one which would customise the encoding used within Intruder. This needed to implement the IIntruderPayloadProcessor [5]  interface. With BurpExtenderForge I can goto the tab "IIntruderPayloadProcessor" which has a template for it. The important part of this extender is the definition of the "processPayload" method. The template definition is shown below:

currentPayload - The value of the payload to be processed.
originalPayload - The value of the original payload prior to processing by any already-applied processing rules.
baseValue - The base value of the payload position, which will be replaced with the current payload.
The value of the processed payload. This may be null to indicate that the current payload should be skipped, and the attack will move directly to the next payload.
def processPayload(self, currentPayload, originalPayload, baseValue):
    # Original arguments are byte arrays.
    # Convert to string as shown.
    currentPayloadString = currentPayload.tostring() 
    originalPayloadString = originalPayload.tostring()
    baseValueString = baseValue.tostring()
    # Simply convert payload to uppercase
    answer = currentPayloadString.upper() 

    # return needs a byte array again. If you have a string use "stringTobBytes"
    return self._helpers.stringToBytes(answer)

For each payload Intruder is going to send, this will convert the text to upper case. I think this was the test case from PortSwigger themselves but I cannot remember now. It might of been me.

To pull it all together excuse my ramblings in the video below. It covers how to temporarily enable the above code. Then shows a slightly more complicated IIntruderPayloadProcessor example where the payload is modified heavily before being sent:



Now off you go and make your Extenders in burp!