0407 | Extending Burp
Introduction
-
Extending Burp Suite
- Burp Suite is a popular web application proxy
- often used by web application hackers
- Burp Extender lets you extend the default functionality of Burp Suite
- Popular extensions exists to automate security testing
- Interface with Burp Suite using a number of APIs
- Burp is written in Java, but we can use Python to create extensions by using Jython (java implementation of python)
- Burp Suite is a popular web application proxy
-
Steps to create an Extension
- Install Jython
- Download Jython
- configure burp with it's location (in the extender options tab)
- Create a Python script with (at least) a
BurpExtender
class - Adding the functionality within the script
- Load the script in the extender tab
- Install Jython
Custom Burp Extension
Did Not Work For Me When Tested
Sadly, it dit not work for me due to version differences.
-
Preparing Burp Suite
- download
- https://portswigger.net/
- "Products" > "Burp Suite Community Edition"
- install
- use default settings
- Jython settings
- "Burp Suite" > "Extensions" > "Extensions settings" > "Extension" > "Python environment" > "Location of Jython standalone JAR file:" > point it to the
.jar
file
- "Burp Suite" > "Extensions" > "Extensions settings" > "Extension" > "Python environment" > "Location of Jython standalone JAR file:" > point it to the
- Helper Addition | to make debugging burp extensions easier
- download
- Quick guide > link > Raw > Save it to the directory where the Burp extensions will be written (documentspython201..)
- make sure to the file has the
.py
extension
- make sure to the file has the
- download
-
Preparing Jython
- download
- https://www.jython.org/
- "Download" > "Jython Standalone" > "Versions" > "Browser"
- Burp Suite API -- Burp Suite > Extensions > APIs
- look for
ITab
(not found)
- look for
- adding the module to burp
- "Burp Suite" > "Extensions" > "Installed" > "Add"
- Extension type | Python
- Extension file |
burp_module.py
- download
-
demo-example | "burp_module.py" | (play around with commenting/uncommenting as you see fit)
# for creating the gui in burp
from burp import IBurpExtender, ITab
from javax import swing
from java.awt import BorderLayout
# others
import sys, time, socket, threading
from exceptions_fix import FixBurpExceptions
# implement the burp extender interface
# -- required by burp for an extension
class BurpExtender(IBurpExtender, ITab):
def registerExtenderCallbacks(self, callbacks):
self.clicked = False
self.response_data = None
self.kill_threads = False
sys.stdout = callbacks.getStdout()
self.callbacks = callbacks
self.callbacks.setExtensionName("Bind shell")
self.tab = swing.JPanel(BorderLayout())
# adding more components onto our tab
# creating the panel
text_panel = swing.JPanel()
# create the boxes
box_vertical = swing.Box.createVerticalBox()
box_horizontal = swin.Box.createHorizontalBox()
# text area to interact with -- specifying the target
self.ip_address = swing.JTextArea('', 2, 100)
# wrap the lines
self.ip_address.setLineWrap(True)
# adding a border
self.ip_address.border = swing.BorderFactory.createTitledBorder("IP Address:")
# add to the horizontal box
box_horizontal.add(self.ip_address)
# add horizontal box to the vertical box
box_vertical.add(box_horizontal)
# text area to interact with -- specifying the command
# create horizontal box
box_horizontal = swing.Box.createHorizontalBox()
self.user_command = swing.JTextArea('', 2, 100)
self.user_command.setLineWrap(True)
self.user_command.border = swing.BorderFactory.createTitledBorder("Command:")
box_horizontal.add(self.user_command)
box_vertical.add(box_horizontal)
# Creating the buttons
box_horizontal = swing.Box.createHorizontalBox()
button_panel = swing.JPanel()
# adding the buttons -- connect;send;disconnect
self.connect_button = swing.JButton('[ --- Connect --- ]', actionPerformed=self.connect)
self.send_button = swing.JButton('[ --- Send Command --- ]', actionPerformed=self.send)
self.disconnect_button = swing.JButton('[ --- Disconnect --- ]', actionPerformed=self.disconnect)
# by default, we do not want to be able to press the disconnect button
self.disconnect_button.enabled = False
# also do not want to be sending anything to nowhere
self.send_button.enabled = False
# add the buttons to the panel
button_panel.add(self.connect_button)
button_panel.add(self.send_button)
button_panel.add(self.disconnect_button)
# adding the button panel
box_horizontal.add(button_panel)
box_vertical.add(box_horizontal)
# adding the text area -- to see the interaction between burp and the bind shell
box_horizontal = swing.Box.createHorizontalBox()
self.output = swing.JTextArea('', 25, 100)
self.output = setLineWrap(True)
self.output = setEditable(False )
# add the scroll pane
scroll = swing.JScrollPane(self.output)
box_horizontal.add(scroll)
box_vertical.add(box_horizontal)
# add the vertical box to the panel
text_panel.add(box_vertical)
# add the text panel to the tab
self.tab.add(text_panel)
callbacks.addSuiteTab(self)
return
def getTabCaption(self):
return "Bind shell"
def getUIComponent(self):
return self.tab
# adding the button functions
# button clicks are associated with a type of event
def send(self, event):
# variable used to later talk to our threads
self.clicked = True
# sleep for half a sec -- race condition
# prevent the burp gui from locking up
time.sleep(0.5)
self.output.text = self.response_data
# create the threads
def send_thread(self):
while True:
if self.kill_threads:
sys.exit()
if self.clicked:
self.clicked = False
# process the message -- send the user's command
self.s.send(self.user_command.text)
def recv_thread(self):
while True:
if self.kill_threads:
sys.exit()
data = self.s.recv(4096).replace("Enter Command> ", "")
if data:
self.response_data = data
def connect(self, event):
try:
# create the socket
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect to the ip the user enters into the text field
self.s.connect((self.ip_address.text, 1234))
# tell the process not to kill our threads
self.kill_threads = False
# set up a few threads -- we want to send and receive data at the same time
# -- without hanging the already existing burp gui
threading.Thread(target=self.send_thread).start()
threading.Thread(target=self.recv_thread).start()
# clean up the gui
self.connect_button.enabled = False
self.disconnect_button.enabled = True
self.send_button.enabled = True
self.ip_address.enabled = False
# print out some useful msg
self.output.text = "Connected to bind shell!"
except:
self.output.text = "Could not connect, try again!"
def disconnect(self, event):
# send exit to the bind shell
self.s.send("exit")
# close the socket
self.s.close()
# tell the process we want to kill our threads
self.kill_threads = True
# clean up the gui
self.connect_button.enabled = True
self.disconnect_button.enabled = False
self.send_button.enabled = False
self.ip_address.enabled = True
self.output.text = "Disconnected from bind shell!"
FixBurpExceptions()