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))