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:

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

Byte Array

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:

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

To convert an existing list to a Java array:

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:

IBurpExtenderCallbacks

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

def registerExtenderCallbacks (self, callbacks)

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

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

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

self._helpers = callbacks.getHelpers()

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

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

IContextMenuFactory

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

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

getHTTPService

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

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

#!/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

HttpListener

Reference

Last updated