Skip to main content

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

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
    • 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
    • Helper Addition | to make debugging burp extensions easier
  • Preparing Jython

    • download
    • Burp Suite API -- Burp Suite > Extensions > APIs
      • look for ITab (not found)
    • adding the module to burp
      • "Burp Suite" > "Extensions" > "Installed" > "Add"
      • Extension type | Python
      • Extension file | burp_module.py
  • 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()