Home  ›  All Blogs  ›  hariprasad  › 

Writing Your Own Burp Suite Extensions

    hariprasad
    25-March-2021

Writing Your Own Burp Suite Extensions

Have you ever thought of writing your own burp extension?

This post will walk you through the entire process of writing your own burp extension in an effortless manner. We’ll start by writing a hello world program and then move on to writing a burp extension that beautifies JSON data using python language.

JSON beautifier! The whole point of this blog is to help you grasp the basics and to provide you an overview regarding this.

Burp Environment Setup

To begin with, we’ll start by setting up our Jython (an implementation of the Python programming language designed to run on the Java platform) environment.

  • Grab your Jython Standalone file from here.

  • Open your Burp suite.

  • Configure Python Environment - Extender > Options > Python Environment > Select fille.

Burp Environment Setup

Now create a new file with extension .py. Then open the file in your favorite text editor.

Let’s begin by importing the modules we’ll need to turn on the features.

Necessary Modules

Let us take you through the modules for a rundown on setting up the extension.

from burp import IBurpExtender               
# This module must be implemented by any burp extension.
from burp import IMessageEditorTab 
# This will help us to create a new custom tab within Burp's HTTP message editor.
from burp import IMessageEditorTabFactory
# provide custom rendering or editing of HTTP messages, within Burp's HTTP editor.
import JSON
#used to manipulate JSON data.


Burp offers multiple APIs, which helps us to develop the Burb extension effortlessly. The details regarding these APIs are available in the extender tab inside the Burp suite. IBurpExtender is required for the all-burp extensions. The IMessageEditorTabFactory and IMessageEditorTab. helps to display the messages in the Burp message tab. The JSON module will help us to beautify JSON data.

Hello World Program

class BurpExtender(IBurpExtender):
# Implement IBurpExtender class

	
	def registerExtenderCallbacks(self,callbacks):


		callbacks.setExtensionName("Hello World")
        # Defining our extension name
        
        print("Hello World")
       
       # Displaying Hello World Message


		return 

The IBurpExtender class is necessary to build burp extensions. The burp will in turn look for the IBurpExtender class and then call the registerExtenderCallbacks() on this object passing in a “callback” object. The callbacks.setExtensionName is set as our extension name and the print function will print the hello world message to the screen.

Now save the file and open it in Burp.

Add new extension: Extender > Extensions > Add > Extension Details > Extension Type: Python > Select extension file.

Burp_hello_world_program

Awesome, now we have done our first ever hello world burp extension. Now let’s put to good use what you’ve learned right now. In the following passage, I’ll explain how to beautify JSON data.

JSON Beautifier

#defining json content types 
json_ContentTypes = [
    "application/json",
    "text/json",
    "text/x-json",
]

class BurpExtender(IBurpExtender,IMessageEditorTabFactory):
    # Implement IBurpExtender class

	def registerExtenderCallbacks(self, callbacks):

		
		self._callbacks = callbacks 
        # reference to our callbacks object.
		self._helpers = callbacks.getHelpers()
        # obtain an extension helpers object.
		callbacks.setExtensionName("JSON Beautifier") 
        # set our extension name.
		callbacks.registerMessageEditorTabFactory(self) 
        # register ourselves as a message editor tab factory.

		return
	
	def createNewInstance(self, controller, editable):
        # This allow us to create new tab within the Burp's HTTP tabs 
        # and it returns the instance of a class that implements the iMessageEditorTab class.

		return Display_data(self, controller, editable)


In simple terms the extension identifies JSON requests by looking into its content-type header, a list of content-type headers acts as the reference point and allows us to match up with the request content header to identify the JSON request.

The lines self._callbacks and self._helpers in a sense helps us to call the object from anywhere in the class. Similarly, the callbacks.registerMessageEditorTabFactory is required to implement a new tab. The createNewInstance() method helps us to generate a new tab within the Burp’s HTTP tabs and returns the instance of a class that implements the iMessageEditorTab class.

class Display_data(IMessageEditorTab):
	# This class define the new message tab.

	def __init__(self, extender, controller, editable):

		
		self._txtInput = extender._callbacks.createTextEditor()
		# create an instance of Burp's text editor, to display our JSON beautified data.
		self._extender = extender

	def getUiComponent(self):
		'''invoke this method before it displays a new HTTP
		 message, so that the custom tab can indicate whether it should be enabled for that message.''' 
		return self._txtInput.getComponent()

	def getTabCaption(self):
		# This method return the tab name.
		return "JSON  Beautifier"


The Display_data class implements Burp’s IMessageEditorTab to create the custom tab with the arguments, extender controller and edit. The extender is an instance of the burp extender class much like the controller, which acts as an instance for the I message editor. The editable is a Boolean value(logic that produces true or false value) which indicates that whether or not the tab is editable by the user also the class handles some logical operations such as if the tab and its message get displayed or not.

Accessing HTTP Request And Beautifying Request Body

def isEnabled(self, content, isRequest):
		'''This method to display a new message or to clear the existing message'''


		if isRequest == True:
			request = self._extender._helpers.analyzeRequest(content)
			self._headers = request.getHeaders()
			for headers in self._headers:
				if headers.lower().startswith("content-type:"):
					content_type = headers.split(":")[1].lower()
					
					for ContentTypes in json_ContentTypes:
						if content_type.find(ContentTypes) > 0:

							requestBody = content[request.getBodyOffset():].tostring()
							
							
							try:
								 self._Beautifier = json.dumps(json.loads(requestBody), sort_keys=True, indent=4)
							except:
								print "Unable to format JSON data"
							
					

			
        return isRequest

	def setMessage(self, content, isRequest):
		#This method returns the currently displayed message.


		if (content is None):
			self._txtInput.setText(None)
			self._txtInput.setEditable(False)
		else:

			self._txtInput.setText(self._Beautifier)
		return


The content and isrequest parameters are accepted by the isEnabled method; if the isrequest parameter is true, then Burp extender will extract the request using self._extender._helpers.analyzeRequest(content). Accordingly using the request.getHeaders(), we are able to assign the HTTP request headers to the self._headers. With the help of for loop, we can extract the content-type header value and it will match up with the JSON content type list that we defined already. If the HTTP request content type header match with the JSON content type, then the program will fetch the request body by using the [request.getBodyOffset():].tostring(). Afterwards we beautify the request data by using json.dumps() method and json.loads() method.

  • json.dumps() : we can convert it into a JSON string
  • json.loads() : we can parse the json data.

We can use the indent keyword argument to specify the indentation size. In the setMessage method, the content will be received and displayed in a new tab. Upon finishing please run the program to see the fruits of your labor.

Burp-json-beautifier

Conclusion

I’m hopeful that none of you guys will have to start from scratch in order to build your own Burp extensions. Even though we have touched the basics of the program, I believe this could present a basic outline for any tech enthusiastic to build and experiment that could inspire and contribute to the community. Feel free to reach out if you have any doubts,

Full Code:

from burp import IBurpExtender               
from burp import IMessageEditorTab           
from burp import IMessageEditorTabFactory
import json


#defining json content types 
json_ContentTypes = [
    "application/json",
    "text/json",
    "text/x-json",
]
# Implement IBurpExtender class
class BurpExtender(IBurpExtender,IMessageEditorTabFactory):

	def registerExtenderCallbacks(self, callbacks):

		# reference to our callbacks object.
		self._callbacks = callbacks 
		# obtain an extension helpers object.
		self._helpers = callbacks.getHelpers()
		# set our extension name.
		callbacks.setExtensionName("JSON Beautifier") 
		# register ourselves as a message editor tab factory.
		callbacks.registerMessageEditorTabFactory(self) 

		return
	# This allow us to create new tab within the Burp's http tabs and it 
	# -returns the instance of a class that implements the iMessageEditorTab class. 
	def createNewInstance(self, controller, editable):

		return Display_data(self, controller, editable)


class Display_data(IMessageEditorTab):
	#This class define the new message tab.

	def __init__(self, extender, controller, editable):

		
		self._txtInput = extender._callbacks.createTextEditor()
		# create an instance of Burp's text editor, to display our JSON beautified data.
		self._extender = extender

	def getUiComponent(self):
		'''invoke this method before it displays a new HTTP
		 message, so that the custom tab can indicate whether it should be enabled for that message.''' 
		return self._txtInput.getComponent()

	def getTabCaption(self):
		#This method return the tab name.
		return "JSON  Beautifier"

	def isEnabled(self, content, isRequest):
		'''This method to display a new message or to clear the existing message'''


		if isRequest == True:
			request = self._extender._helpers.analyzeRequest(content)
			self._headers = request.getHeaders()

			for headers in self._headers:

				if headers.lower().startswith("content-type:"):

					content_type = headers.split(":")[1].lower()
					
					for ContentTypes in json_ContentTypes:

						if content_type.find(ContentTypes) > 0:

							requestBody = content[request.getBodyOffset():].tostring();
							
							
							try:
								 self._Beautifier = json.dumps(json.loads(requestBody), sort_keys=True, indent=4)
							except:
								print "Unable to format JSON data"
							
					

			
			return isRequest

	def setMessage(self, content, isRequest):
		#This method returns the currently displayed message.


		if (content is None):
			self._txtInput.setText(None)
			self._txtInput.setEditable(False)
		else:

			self._txtInput.setText(self._Beautifier)
		return



References

About Payatu

Payatu is a Research Focused, CERT-In impaneled Cybersecurity Consulting company specializing in security assessments of IoT product ecosystem, Web application & Network with a proven track record of securing applications and infrastructure for customers across 20+ countries.

Get in touch with us. Click on the get started button below now.

Get to know more about our process, methodology & team!

Close the overlay

I am looking for
Please click one!