# -*- coding: utf-8 -*-
from burp import IBurpExtender
from burp import ITab
from burp import IHttpListener
from burp import IMessageEditorController
from java.awt import Component;
from java.io import PrintWriter;
from java.util import ArrayList;
from java.util import List;
from javax.swing import JScrollPane;
from javax.swing import JPanel;
from javax.swing import JCheckBox;
from javax.swing import JTextField;
from javax.swing import JSplitPane;
from javax.swing import JTabbedPane;
from javax.swing import JTable;
from javax.swing import JLabel;
# import java.awt.event.ItemListener
from java.awt.event import ItemListener
from javax.swing import SwingUtilities;
from javax.swing.table import AbstractTableModel;
from threading import Lock
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel):
#
# implement IBurpExtender
#
def registerExtenderCallbacks(self, callbacks):
# keep a reference to our callbacks object
self._callbacks = callbacks
# obtain an extension helpers object
self._helpers = callbacks.getHelpers()
self.stdout = PrintWriter(callbacks.getStdout(), True)
self.stdout.println("Hello output1111")
# set our extension name
callbacks.setExtensionName("Custom logger")
# create the log and a lock on which to synchronize when adding log entries
self._log = ArrayList()
self._lock = Lock()
# main split pane
self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT)
# table of log entries
logTable = Table(self)
scrollPane = JScrollPane(logTable)
self._splitpane.setLeftComponent(scrollPane)
# tabs with request/response viewers
tabs = JTabbedPane()
self._requestViewer = callbacks.createMessageEditor(self, False)
self._responseViewer = callbacks.createMessageEditor(self, False)
optionPanel = JPanel()
# chkbox1 = JCheckBox("flgxx",False)
self.globalSwitchChkbox = JCheckBox("globalSwitch")
self.hostFilterLabel = JLabel('| hostFilter')
self.hostFilterText = JTextField("",20)
self.customHeaderChkbox = JCheckBox('customHeaderSwitch')
self.customHeaderLabel =JLabel(' | customHeader')
self.customHeaderText = JTextField('',20)
optionPanel.add(self.globalSwitchChkbox)
optionPanel.add(self.hostFilterLabel)
optionPanel.add(self.hostFilterText)
optionPanel.add(self.customHeaderChkbox)
optionPanel.add(self.customHeaderLabel)
optionPanel.add(self.customHeaderText)
tabs.addTab("Request", self._requestViewer.getComponent())
tabs.addTab("Response", self._responseViewer.getComponent())
tabs.addTab("options",optionPanel)
self._splitpane.setRightComponent(tabs)
# customize our UI components
callbacks.customizeUiComponent(self._splitpane)
callbacks.customizeUiComponent(logTable)
callbacks.customizeUiComponent(scrollPane)
callbacks.customizeUiComponent(tabs)
# add the custom tab to Burp's UI
callbacks.addSuiteTab(self)
# register ourselves as an HTTP listener
callbacks.registerHttpListener(self)
return
#
# implement ITab
#
def getTabCaption(self):
return "Logger"
def getUiComponent(self):
return self._splitpane
#
# implement IHttpListener
#
def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
# only process requests
if messageIsRequest:
return
globalSwitch = self.globalSwitchChkbox.isSelected()
hostFilter = self.hostFilterText.getText()
host = messageInfo.getHttpService().getHost()
customHeaderSwitch = self.customHeaderChkbox.isSelected()
customHeaderText = self.customHeaderText.getText()
if not globalSwitch :
return
if self.isHostInFilter(host,hostFilter) == False:
return
requestInfo = self._helpers.analyzeRequest(messageInfo)
reqBody = messageInfo.getRequest()[requestInfo.getBodyOffset():]
# newHeaders = ModifyMessage.getNewHeaders(requestInfo, None, ["Host: " + newDomain])
newHeaders = requestInfo.getHeaders()
newHeaders.append('xxx:ttt')
for header in newHeaders:
self.stdout.println(header)
newreq = self._helpers.buildHttpMessage(newHeaders, reqBody)
# messageInfo.setRequest(newreq)
# create a new log entry with the message details
self._lock.acquire()
row = self._log.size()
self._log.add(LogEntry(toolFlag, self._callbacks.saveBuffersToTempFiles(messageInfo), self._helpers.analyzeRequest(messageInfo).getUrl()))
self.fireTableRowsInserted(row, row)
self._lock.release()
def isHostInFilter(self,host,filter):
if filter == '':
return True
splits = filter.split('|')
for split in splits:
if host.find(split) != -1:
return True
return False
#
# extend AbstractTableModel
#
def getRowCount(self):
try:
return self._log.size()
except:
return 0
def getColumnCount(self):
return 2
def getColumnName(self, columnIndex):
if columnIndex == 0:
return "Tool"
if columnIndex == 1:
return "URL"
return ""
def getValueAt(self, rowIndex, columnIndex):
logEntry = self._log.get(rowIndex)
if columnIndex == 0:
return self._callbacks.getToolName(logEntry._tool)
if columnIndex == 1:
return logEntry._url.toString()
return ""
#
# implement IMessageEditorController
# this allows our request/response viewers to obtain details about the messages being displayed
#
def getHttpService(self):
return self._currentlyDisplayedItem.getHttpService()
def getRequest(self):
return self._currentlyDisplayedItem.getRequest()
def getResponse(self):
return self._currentlyDisplayedItem.getResponse()
class Table(JTable):
def __init__(self, extender):
self._extender = extender
self.setModel(extender)
def changeSelection(self, row, col, toggle, extend):
# show the log entry for the selected row
logEntry = self._extender._log.get(row)
self._extender._requestViewer.setMessage(logEntry._requestResponse.getRequest(), True)
self._extender._responseViewer.setMessage(logEntry._requestResponse.getResponse(), False)
self._extender._currentlyDisplayedItem = logEntry._requestResponse
JTable.changeSelection(self, row, col, toggle, extend)
#
# class to hold details of each log entry
#
class LogEntry:
def __init__(self, tool, requestResponse, url):
self._tool = tool
self._requestResponse = requestResponse
self._url = url