# Burp Extender

## Entry Point

Burp looks for a class called `BurpExtender` to instantiate (with no constructor parameters) and then calls `registerExtenderCallbacks()` on this object passing in a `callbacks` object. Think of this as the entrypoint for your extension, allowing you to tell Burp what your extension is capable of, and when Burp should ask your extension questions. Example:

```python
from burp import IBurpExtender
class BurpExtender(IBurpExtender):
    def registerExtenderCallbacks( self, callbacks):
        # your extension code here
        return
```

## Byte Array <a href="#h3-3" id="h3-3"></a>

The first important thing to note about programming extensions for Burp is that, for the most part, the data you will be inspecting is provided in the form of byte arrays (`byte[]`) which might take some getting used to if you'd normally program with strings. It's important to understand that while it is possible to convert from byte to a string, this process is not entirely trivial and may bloat the memory usage of your extension. In some cases this is unavoidable (e.g. you need to execute a regex against a request/response), but on the whole you should try to stick to working with bytes directly.

To create a byte-compatible object to pass to the Burp Extender APIs:

```python
bytearray("foo") # In Java, this is equivalent to new byte[] {'f', 'o', 'o'}
```

To convert an existing list to a Java array:

```python
from jarray import array
array([1, 2, 3], 'i') # In Java, this is equivalent to new int[] {1, 2, 3}
```

The various primitive type names can be found in the Jython documentation:

{% embed url="<https://www.jython.org/jython-old-sites/archive/21/docs/jarray.html>" %}
Java Arrays in Jython - JArray
{% endembed %}

## IBurpExtenderCallbacks <a href="#h3-4" id="h3-4"></a>

The `IBurpExtenderCallbacks` method is the entry point of the Burp extension:

```python
def registerExtenderCallbacks (self, callbacks)
```

The first useful thing you can do with the callbacks object is to tell Burp what your extension name is:

```python
callbacks.setExtensionName("This is the plugin's name")
```

Get a copy of the helpers to make your life easier:

```python
self._helpers = callbacks.getHelpers()
```

The complete list of helper APIs can be found at the following link:

{% embed url="<https://portswigger.net/burp/extender/api/burp/iextensionhelpers.html>" %}
IExtensionHelpers - burp extender API
{% endembed %}

```python
from burp import IBurpExtender
class BurpExtender(IBurpExtender):
    def registerExtenderCallbacks( self, callbacks):
        callbacks.setExtensionName("This is the plugin's name")
        return
```

## IContextMenuFactory <a href="#h3-5" id="h3-5"></a>

```python
from burp import IBurpExtender
from burp import IContextMenuFactory

from javax.swing import JMenu
from javax.swing import JMenuItem

class BurpExtender(IBurpExtender, IContextMenuFactory):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        callbacks.setExtensionName("test")
        callbacks.registerContextMenuFactory(self)

    def createMenuItems(self, invocation):
        menu = []
        menu.append(JMenuItem('Test menu', None, actionPerformed=self.testmenu)) 
        return menu

    def testmenu(self,event):
        print(event)
```

## IContextMenuInvocation

```python
from burp import IBurpExtender
from burp import IContextMenuFactory
from burp import IBurpExtenderCallbacks

from javax.swing import JMenu
from javax.swing import JMenuItem

class BurpExtender(IBurpExtender, IContextMenuFactory):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        callbacks.setExtensionName("test")
        callbacks.registerContextMenuFactory(self)

    def createMenuItems(self, invocation):
        menu = []
        if invocation.getToolFlag() == IBurpExtenderCallbacks.TOOL_REPEATER:
            menu.append(JMenuItem("Test menu", None, actionPerformed=self.testmenu))
        return menu

    def testmenu(self, event):
        print("aaaa")
```

## IHttpRequestResponse <a href="#h3-7" id="h3-7"></a>

getHTTPService

```python
from burp import IBurpExtender
from burp import IHttpListener

class BurpExtender(IBurpExtender, IHttpListener):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks

        callbacks.setExtensionName("test")
        callbacks.registerHttpListener(self)

    def processHttpMessage(self, toolflag, messageIsRequest, messageInfo):
        service = messageInfo.getHttpService()
        print("Host: " + str(service.getHost()))
        print("Port: "+ str(service.getPort()))
        print("Protocol: " + str(service.getProtocol()))
        print("-----------------------------------")
```

setHighlight

```python
from burp import IBurpExtender
from burp import IHttpListener

class BurpExtender(IBurpExtender, IHttpListener):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks

        callbacks.setExtensionName("test")
        callbacks.registerHttpListener(self)

    def processHttpMessage(self,toolflag,messageIsRequest,messageInfo):
        messageInfo.setHighlight('blue')
```

unicode

```python
#!/usr/bin/env python
#coding=utf8
from burp import IBurpExtender
from burp import IHttpListener
from burp import IHttpRequestResponse
from burp import IResponseInfo

import re
# Class BurpExtender (Required) contaning all functions used to interact with Burp Suite API

print 'stayliv3.github.io'

class BurpExtender(IBurpExtender, IHttpListener):

    # define registerExtenderCallbacks: From IBurpExtender Interface 
    def registerExtenderCallbacks(self, callbacks):

        # keep a reference to our callbacks object (Burp Extensibility Feature)
        self._callbacks = callbacks
        # obtain an extension helpers object (Burp Extensibility Feature)
        # http://portswigger.net/burp/extender/api/burp/IExtensionHelpers.html
        self._helpers = callbacks.getHelpers()
        # set our extension name that will display in Extender Tab
        self._callbacks.setExtensionName("unicode decode")
        # register ourselves as an HTTP listener
        callbacks.registerHttpListener(self)

    # define processHttpMessage: From IHttpListener Interface 
    def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):

        # determine what tool we would like to pass though our extension:
        if toolFlag == 64 or toolFlag == 16 or toolFlag == 32: #if tool is Proxy Tab or repeater
            # determine if request or response:
            if not messageIsRequest:#only handle responses
                response = messageInfo.getResponse()
                 #get Response from IHttpRequestResponse instance
                analyzedResponse = self._helpers.analyzeResponse(response) # returns IResponseInfo
                headers = analyzedResponse.getHeaders()
                #替换iso8859-1
                # iterate though list of headers
                new_headers = []
                for header in headers:
                    # Look for Content-Type Header)
                    if header.startswith("Content-Type:"):
                        # Look for HTML response
                        # header.replace('iso-8859-1', 'utf-8')
                        # print header
                        new_headers.append(header.replace('iso-8859-1', 'utf-8'))
                    else:
                        new_headers.append(header)

                print new_headers

                body = response[analyzedResponse.getBodyOffset():]
                body_string = body.tostring()
                # print body_string
                u_char_escape = re.search( r'(?:\\u[\d\w]{4})+', body_string)
                if u_char_escape:
                    # print u_char_escape.group()
                    u_char = u_char_escape.group().decode('unicode_escape').encode('utf8')
                    new_body_string = body_string.replace(u_char_escape.group(),'--u--'+u_char+'--u--')
                    new_body = self._helpers.bytesToString(new_body_string)
                    # print new_body_string
                    messageInfo.setResponse(self._helpers.buildHttpMessage(new_headers, new_body))
```

## IHttpService <a href="#h3-8" id="h3-8"></a>

#### HttpListener <a href="#h3-9" id="h3-9"></a>

## Reference

{% embed url="<https://portswigger.net/burp/extender/writing-your-first-burp-suite-extension>" %}
Writing your first Burp Suite extension - PortSwigger
{% endembed %}
