Skip to content

Writing Burp Suite Extension in Python – Part 2

Burp Suite Extension

In part 1 we have seen basic burp suite APIs to create a burp suite extension which does nothing. In this part, we will work on the GUI part for our extension. We will look at how to create a basic GUI like table, button, and action listener for buttons, text boxes etc.

Java Swing and AWT

If you have worked on Java language and specifically to create desktop applications or anything which requires GUI, as might have used the swing and awt. The Swing and AWT are Java APIs to create GUI application and allows you to create all types of GUI. moreover, If you have worked on these APIs in java it won’t be challenging for you to create GUI.

The Swing and AWT are part of Java with all the documentation available on oracle. Hence to create a GUI in Jython, we will use both APIs. As APIs are part of Java so we have to use this API with the syntax of python.

Burp Suite with Jpanel

Jpanel is part of the java swing API and it is the first thing you will use to create a GUI. Overall the Jpanel is nothing but just a way to create an open layout or body. To clarify you can think of it as an HTML structure like a body tag which creates a UI for the page and every content will be part of the body.

from javax.swing import JPanel

panelui = JPanel()

The above code is just simple. To summarise we are importing the API from Javax. And with that on line number 3, we are creating a UI. To create an extension we need to add the default extension code which we looked at in the last article.

from burp import IBurpExtender
from javax.swing import JPanel


class BurpExtender(IBurpExtender):

    def registerExtenderCallbacks(self, callbacks):
        self.callbacks = callbacks
        self.callbacks.printOutput("Our Test Extension")
        panelui = JPanel()

        

If we load the above code in the burp suite, you won’t notice anything. Also, it will not show any UI in the burp even after creating a panel. The reason for this is because we have created a UI or a body but to show a UI, we need to tell the burp that we want to show our UI and for that, we need to create a tab. So we need to create a tab like a repeater, proxy etc.

So to add a custom tab in the burp suite, we need a few things. First, we need to use the Burp ITab API. The API needs a few things like we need to use this API to tell the name of our extension and what is the UI it will show in the custom tab. These 2 things are required, apart from that, we need to create a UI.

Burp Suite Custom Tab

Firstly we need to look at the ITab documentation to check all the methods we need to implement. If we look at the yellow part in the below image. ITab requires us to use the callback method for addsuitetab. Also, the ITab interface has 2 methods and we need to implement them.

itab
from burp import ITab

class BurpExtender(IBurpExtender, ITab):

    def registerExtenderCallbacks(self, callbacks):
        self.callbacks = callbacks

    def getTabCaption(self):
    	return "Custom Tab"

Observe the above GetTabCaption code. Firstly we have imported the ITab from burp. Then we have the default burp class but have added the ITab in the class. On line number 8 we have created a method inside the class and with the self keyword, we are referring it to the current class which will use the ITab. On the last line, we are returning the tab name for our extension. The above code will only tell the name of our extension to the burp suite.

from burp import ITab
from burp import IBurpExtender
from javax.swing import JPanel

class BurpExtender(IBurpExtender, ITab):

    def registerExtenderCallbacks(self, callbacks):
        self.callbacks = callbacks
        self.Customtabui = JPanel()
        self.callbacks.setExtensionName("Test Extension")
        self.callbacks.addSuiteTab(self)

    def getTabCaption(self):
    	return "Custom Tab"

    def getUiComponent(self):
    	return self.Customtabui

The above test.py code will create an actual tab for us. On line number 8 we have created a UI or body as seen above. On line 11 we have used the callback method as mentioned in the documentation. The addsuitetab will ask burp to add a custom tab for this extension. Also with the self keyword, we are referring to the current class to look for which tab to add.

On line number 16, we have a method that will return the UI for the extension. Overall we have done the following things.

  • self.Customtabui = JPanel() – To create a Body or UI.
  • self.callbacks.addSuiteTab(self) – Asked burp to add the new tab from the current class.
  • getTabCaption – Method to return the name of our tab.
  • getUiComponent – Return the body which will be displayed on the custom tab.
New Custom tab

JTextField

So far we have created an empty tab for our extension and have added a body or Jpanel for it. From now we will add some UI components inside our extension. Let’s start with the text field, It is similar to the HTML input box which will have a text field to type.

We will look at how we can create a text field and later add it inside our burp UI. Also how we can set the default text for our text field.

from burp import ITab
from burp import IBurpExtender
from javax.swing import JPanel
from javax.swing import JTextField

class BurpExtender(IBurpExtender, ITab):

    def registerExtenderCallbacks(self, callbacks):
        self.callbacks = callbacks
        self.Customtabui = JPanel()
        self.callbacks.setExtensionName("Test Extension")
        self.callbacks.addSuiteTab(self)

        self.myinputbox = JTextField(100)
        self.myinputbox.setText("hello world")
        self.Customtabui.add(self.myinputbox)

    def getTabCaption(self):
    	return "Custom Tab"

    def getUiComponent(self):
    	return self.Customtabui

In the above code, as required we have imported the JTextField then we have created a textbox on line number 14. Here 100 defines the size of the text box. Then on the very next line, we have set a default value for our text box.

In the previous part, we have seen that for our custom tab we have returned the Customtabui which is using jpanel. So burp will show the Customtabui inside our tab for UI. Every component inside the Customtabui will be directly shown in the UI. On line number 16 we have added our textbox inside the Customtabui.

So all our components will be added inside the one jpanel and that jpanel will be used by the burp for the UI.

Apart from this, we need one more thing which is fetching the text inside the text field. We can use the below code to do it.

inputtext = self.myinputbox.getText()
self.callbacks.printOutput(inputtext)

The above code will fetch text output for us. We have one more thing related to fetching the data. In a certain scenario, we want to fetch the data once the user has edited the value of the text field. We can do that in 2 ways, either add an event or document listener that will allow us to fetch data as soon as the user edits it.

Another way is adding a save button that will allow us to verify that users have edited the text if the user clicks on the save button. Now we will see the button part later in this article but the document listener part is out of the scope for now as it requires a little more complex code to add.

JButton

One of the most required components in UI is a button. We will look at how to create and add the button in our Jpanel as well as how to add a listener that will allow us to perform the task once the button is clicked.

from javax.swing import JButton

self.submitbutton = JButton("Submit")
self.Customtabui.add(self.submitbutton)

We are not looking at the whole code and are just adding the above code to our existing code. Here we have created a button named submit. And we have added that in our jpanel which is customtabui.

JButton Action Listener

Now let’s look at how we can implement the action listener for our button. So We have a text box with the default value of “hello world”. We want to get the value of our text field once we click on the submit button and print the output in the Output.

from burp import ITab
from burp import IBurpExtender
from javax.swing import JPanel
from javax.swing import JTextField
from javax.swing import JButton

class BurpExtender(IBurpExtender, ITab):

    def registerExtenderCallbacks(self, callbacks):
        self.callbacks = callbacks
        self.Customtabui = JPanel()
        self.callbacks.setExtensionName("Test Extension")
        self.callbacks.addSuiteTab(self)

        self.myinputbox = JTextField(10)
        self.myinputbox.setText("hello world")
        self.submitbutton = JButton("Submit", actionPerformed=self.submitbuttonlistener)
        self.Customtabui.add(self.myinputbox)
        self.Customtabui.add(self.submitbutton)

    def submitbuttonlistener(self,e):
    	newtext = self.myinputbox.getText()
    	self.callbacks.printOutput(newtext)

    def getTabCaption(self):
    	return "Custom Tab"

    def getUiComponent(self):
    	return self.Customtabui
  • One line number 17 we have a button and have added the action performed method. The action performed is attached with a function/method named as submitbuttonlistener. Every time button is clicked this method/function will be executed.
  • On line number 21 we have the method that will handle the button clicks. So this will get the text of the text box and will print it in the output.

We can see from the above image that it’s printing the output of the text field once we click on the button.

Default Table

The swing API allows us to create a table in multiple ways and to create one we need to use a model. The model is just a way to create a table like a setting or list of features you want in the table. There are two ways to use a model, either we can use a default table model or we can create a custom table model. The default table model also allows us to extend the functions but only a limited part is allowed so we are not going to see how to do that as it’s better to create a custom model.

from burp import ITab
from burp import IBurpExtender
from javax.swing import JPanel
from javax.swing import JTable
from javax.swing import JScrollPane
from javax.swing.table import DefaultTableModel

class BurpExtender(IBurpExtender, ITab):

    def registerExtenderCallbacks(self, callbacks):
        self.callbacks = callbacks
        self.Customtabui = JPanel()
        self.callbacks.setExtensionName("Test Extension")
        self.callbacks.addSuiteTab(self)
        
        self.colname = ['Number','String']
        self.rowvalue = [['1','One'],['2','Two']]
        self.DefaultModel = DefaultTableModel(self.rowvalue, self.colname)
    	self.table = JTable(self.DefaultModel)
    	self.scrollPane = JScrollPane()
    	self.scrollPane.getViewport().setView((self.table))
    	self.Customtabui.add(self.scrollPane)

    def getTabCaption(self):
    	return "Custom Tab"

    def getUiComponent(self):
    	return self.Customtabui

Looking at the code the first thing is importing the required APIs. So we have imported the JTable, Default table and JScrollPane which allows us to add a scroll bar to our table.

On lines number 16 and 17 we have created the name of our columns and rows. As of now, we have static data in the table for the rows.

Line number 18 is where we have created a default table model and have given the columns and rows. We can use None keyword in case we want to keep the table empty and only add data dynamically after a certain action.

Now we have created a Jtable and assigned the model we want our table to use. Later on-line numbers 20 and 21 we created a scroller and given the table on which we want the scroller.

rowdata = ['3', 'Three']
self.DefaultModel.addRow(rowdata)

You can use the above code to add a row anytime you want to update the table dynamically. You can add this with a button or anything which can update the data dynamically. There are more ways to do like deleting rows, fetching data etc. You can check out the documentation.

Custom Table

The custom table model is the most important part and many times the default model doesn’t allow us to do certain tasks. The code will be similar to the above default model code. The Jtable part will be the same only difference is instead of adding the default table model in Jtable we will create a custom model.

from burp import ITab
from burp import IBurpExtender
from javax.swing import JPanel
from javax.swing import JTable
from javax.swing import JScrollPane
from javax.swing.table import AbstractTableModel

class BurpExtender(IBurpExtender, ITab):

    def registerExtenderCallbacks(self, callbacks):
        self.callbacks = callbacks
        self.Customtabui = JPanel()
        self.callbacks.setExtensionName("Test Extension")
        self.callbacks.addSuiteTab(self)
        self.mytable = CustomTable()
        self.scrollPane = JScrollPane()
        self.scrollPane.getViewport().setView((self.mytable))
        self.Customtabui.add(self.scrollPane)

    def getTabCaption(self):
    	return "Custom Tab"

    def getUiComponent(self):
    	return self.Customtabui

class CustomDataTableModel(AbstractTableModel):
	def getColumnCount(self):
		return 2

	def getRowCount(self):
		return 1

	def getValueAt(self, row, column):
		if column == 0:
			return "1"
		if column == 1:
			return "One"

	def getColumnName(self, column):
		if column == 0:
			return "Number"

		if column == 1:
			return "String"
		return ""

class CustomTable(JTable):
  
    def __init__(self):
        self.setModel(CustomDataTableModel())
        self.setRowSelectionAllowed(True)
        self.setAutoCreateRowSorter(True)

The code is straightforward. We have imported the table, JScrollPane and AbstractTableModel to create or extend our model. The code between lines number 15 to 19 is similar to the previous one instead of default we have the custom model here.

From line number 26, we have created another class to create our custom model for the table. Remember all the code in our class from lines 26 to 45 is the default code. The meaning of default is this particular code must be there in your model else you will get some errors. You can add more methods whatever you want but for our demo or example, it’s good enough to work with.

Also in our model, we have added the static value for everything like row values, row counts etc. As of now, it is not an issue for us. We will look at how to add more to our model to add data dynamically later on in this series. Meanwhile, you can check out the documentation for AbstractTableModel.

From line number 47 onward we have another class for JTable to add or tell JTable which model to use. Also, we have added some customization to our table. You can use the same way to extend the default table model as well.

We have a lot more to add or customize with our table but we don’t want to make it complex. For now, so we will look at It while we work on the actual extension.

Follow us

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.