class BeautifierOptionsPanel(JScrollPane): def __init__(self, extender): super(BeautifierOptionsPanel, self).__init__() self._extender = extender self.contentWrapper = JPanel(GridBagLayout()) self.setViewportView(self.contentWrapper) self.getVerticalScrollBar().setUnitIncrement(16) self.addMouseListener(self.RequestFocusListener( self)) # Let textArea lose focus when click empty area innerContainer = JPanel(GridBagLayout()) innerContainer.setFocusable( True ) # make sure the maxSizeText TextField is not focused when BeautifierOptionsPanel display # generalOptionPanel and it's inner component maxSizeLabel = JLabel("Max Size: ") self.maxSizeText = JTextField(5) self.maxSizeText.setHorizontalAlignment(SwingConstants.RIGHT) self.maxSizeText.addFocusListener(self.MaxSizeTextListener(self)) sizeUnitLabel = JLabel("KB") generalOptionPanel = JPanel(GridBagLayout()) generalOptionPanel.setBorder( BorderFactory.createTitledBorder("General Options")) gbc = GridBagConstraints() gbc.anchor = GridBagConstraints.WEST gbc.gridx = 0 gbc.gridy = 0 generalOptionPanel.add(maxSizeLabel, gbc) gbc.fill = GridBagConstraints.HORIZONTAL gbc.gridx = 1 gbc.gridy = 0 generalOptionPanel.add(self.maxSizeText, gbc) gbc.fill = GridBagConstraints.NONE gbc.gridx = 2 gbc.gridy = 0 gbc.weightx = 1.0 generalOptionPanel.add(sizeUnitLabel, gbc) gbc = GridBagConstraints() gbc.fill = GridBagConstraints.BOTH gbc.gridx = 1 gbc.gridy = 0 gbc.gridheight = 2 innerContainer.add(generalOptionPanel, gbc) # messageTabOptionPanel and it's inner component self.messageTabFormatCheckBoxs = [] for f in supportedFormats: ckb = JCheckBox(f) ckb.addItemListener(self.messageTabFormatListener) self.messageTabFormatCheckBoxs.append(ckb) messageTabOptionPanel = JPanel() messageTabOptionPanel.setLayout( BoxLayout(messageTabOptionPanel, BoxLayout.Y_AXIS)) messageTabOptionPanel.setBorder( BorderFactory.createTitledBorder("Enable in MessageEditorTab")) for b in self.messageTabFormatCheckBoxs: messageTabOptionPanel.add(b) gbc.gridx = 1 gbc.gridy = 2 gbc.gridheight = 9 innerContainer.add(messageTabOptionPanel, gbc) # replaceResponsePanel and it's inner component self.chkEnableReplace = JCheckBox("Enable") self.chkEnableReplace.addItemListener(self.repalceResponseBoxListener) replaceResponseFormatLabel = JLabel("Format") self.replaceResponseFormatCheckBoxs = [] for f in supportedFormats: ckb = JCheckBox(f) ckb.addItemListener(self.replaceResponseFormatListener) self.replaceResponseFormatCheckBoxs.append(ckb) replaceResponseIncludeLabel = JLabel( "Include URL that matches below(one item one line)") self.URLIncludeTextArea = JTextArea(6, 32) self.URLIncludeTextArea.addFocusListener( self.URLIncludeFocusListener(self)) URLIncludeScrollPane = JScrollPane(self.URLIncludeTextArea) URLIncludeScrollPane.setAlignmentX(Component.LEFT_ALIGNMENT) replaceResponseExcludeLabel = JLabel( "Exclude URL that matches below(one item one line)") self.URLExcludeTextArea = JTextArea(5, 32) self.URLExcludeTextArea.addFocusListener( self.URLExcludeFocusListener(self)) URLExcludeScrollPane = JScrollPane(self.URLExcludeTextArea) URLExcludeScrollPane.setAlignmentX(Component.LEFT_ALIGNMENT) replaceResponsePanel = JPanel() replaceResponsePanel.setLayout( BoxLayout(replaceResponsePanel, BoxLayout.Y_AXIS)) replaceResponsePanel.setBorder( BorderFactory.createTitledBorder("Replace PROXY Response")) replaceResponsePanel.add(self.chkEnableReplace) replaceResponsePanel.add(Box.createVerticalStrut(10)) replaceResponsePanel.add(replaceResponseFormatLabel) for b in self.replaceResponseFormatCheckBoxs: replaceResponsePanel.add(b) replaceResponsePanel.add(Box.createVerticalStrut(10)) replaceResponsePanel.add(replaceResponseIncludeLabel) replaceResponsePanel.add(URLIncludeScrollPane) replaceResponsePanel.add(Box.createVerticalStrut(10)) replaceResponsePanel.add(replaceResponseExcludeLabel) replaceResponsePanel.add(URLExcludeScrollPane) gbc.gridy = 11 innerContainer.add(replaceResponsePanel, gbc) # let innerContainer keep away from left and up gbc = GridBagConstraints() gbc.gridx = 1 gbc.gridy = 1 self.contentWrapper.add(Box.createHorizontalStrut(15), gbc) # gbc.ipadx = gbc.ipady = 25 gbc.gridx = 2 self.contentWrapper.add(innerContainer, gbc) # let innerContainer stay left side gbc = GridBagConstraints() gbc.gridx = 3 gbc.gridy = 2 gbc.gridwidth = 1 gbc.weightx = gbc.weighty = 1 paddingPanel = JPanel() self.contentWrapper.add(paddingPanel, gbc) self.setDefaultOptionDisplay() def disableReplaceResponseDisplay(self): for chb in self.replaceResponseFormatCheckBoxs: chb.setEnabled(False) self.URLIncludeTextArea.setEnabled(False) self.URLExcludeTextArea.setEnabled(False) def enableReplaceResponseDisplay(self): for chb in self.replaceResponseFormatCheckBoxs: chb.setEnabled(True) self.URLIncludeTextArea.setEnabled(True) self.URLExcludeTextArea.setEnabled(True) def setDefaultOptionDisplay(self): self.maxSizeText.setText( str(options.get("general").get("dataMaxSize") / 1024)) for chb in self.messageTabFormatCheckBoxs: format = chb.getText() chb.setSelected(options.get("messageEditorTabFormat").get(format)) self.chkEnableReplace.setSelected( options.get("replaceProxyResponse").get("enable")) for chb in self.replaceResponseFormatCheckBoxs: format = chb.getText() chb.setSelected( options.get("replaceProxyResponse").get("formats").get(format)) self.URLIncludeTextArea.setText("\n".join( options.get("replaceProxyResponse").get("include", []))) self.URLExcludeTextArea.setText("\n".join( options.get("replaceProxyResponse").get("exclude", []))) if self.chkEnableReplace.isSelected(): self.enableReplaceResponseDisplay() else: self.disableReplaceResponseDisplay() def saveOptions(self): if self._extender: self._extender._callbacks.saveExtensionSetting( "options", json.dumps(options)) class RequestFocusListener(MouseAdapter): def __init__(self, beautifierOptionsPanel): super(BeautifierOptionsPanel.RequestFocusListener, self).__init__() self.beautifierOptionsPanel = beautifierOptionsPanel def mouseClicked(self, e): self.beautifierOptionsPanel.requestFocusInWindow() class MaxSizeTextListener(FocusListener): def __init__(self, beautifierOptionsPanel): super(BeautifierOptionsPanel.MaxSizeTextListener, self).__init__() self.beautifierOptionsPanel = beautifierOptionsPanel def focusGained(self, e): pass def focusLost(self, e): size = e.getSource().getText() try: size = int(float(size)) options.get("general").update({"dataMaxSize": size * 1024}) e.getSource().setText(str(size)) self.beautifierOptionsPanel.saveOptions() except: e.getSource().setText( str(options.get("general").get("dataMaxSize") / 1024)) def messageTabFormatListener(self, e): format = e.getSource().getText() if e.getStateChange() == ItemEvent.SELECTED: options.get("messageEditorTabFormat").update({format: True}) else: options.get("messageEditorTabFormat").update({format: False}) self.saveOptions() def repalceResponseBoxListener(self, e): if e.getStateChange() == ItemEvent.SELECTED: options.get("replaceProxyResponse").update({"enable": True}) self.enableReplaceResponseDisplay() else: options.get("replaceProxyResponse").update({"enable": False}) self.disableReplaceResponseDisplay() self.saveOptions() def replaceResponseFormatListener(self, e): format = e.getSource().getText() if e.getStateChange() == ItemEvent.SELECTED: options.get("replaceProxyResponse").get("formats").update( {format: True}) else: options.get("replaceProxyResponse").get("formats").update( {format: False}) self.saveOptions() class URLIncludeFocusListener(FocusListener): def __init__(self, beautifierOptionsPanel): super(BeautifierOptionsPanel.URLIncludeFocusListener, self).__init__() self.beautifierOptionsPanel = beautifierOptionsPanel def focusGained(self, e): pass def focusLost(self, e): text = e.getSource().getText() # <unicode> urlPatterns = [ p.strip() for p in text.split("\n") if p.strip() != "" ] options.get("replaceProxyResponse").update( {"include": urlPatterns}) self.beautifierOptionsPanel.saveOptions() class URLExcludeFocusListener(FocusListener): def __init__(self, beautifierOptionsPanel): super(BeautifierOptionsPanel.URLExcludeFocusListener, self).__init__() self.beautifierOptionsPanel = beautifierOptionsPanel def focusGained(self, e): pass def focusLost(self, e): text = e.getSource().getText() # <unicode> urlPatterns = [ p.strip() for p in text.split("\n") if p.strip() != "" ] options.get("replaceProxyResponse").update( {"exclude": urlPatterns}) self.beautifierOptionsPanel.saveOptions()
class BurpExtender(IBurpExtender, IContextMenuFactory, ITab, FocusListener): """custom reporting extension implementation""" def registerExtenderCallbacks(self, callbacks): """extension startup""" # commons self.EXTENSION_NAME = 'Report2text' self.COLOR_RED = Color(0xff6633) self.COLOR_BLACK = Color(0x0) self._callbacks = callbacks self._helpers = self._callbacks.getHelpers() self._callbacks.setExtensionName(self.EXTENSION_NAME) # menu self._callbacks.registerContextMenuFactory(self) # output tab self._mainTextArea = JTextArea('initial text') self._mainTextArea.editable = False self._mainTextArea.setLineWrap(True) self._mainTextArea.setWrapStyleWord(True) self._mainTextArea.addFocusListener(self) self._tab = JPanel(BorderLayout()) self._tab.add(JScrollPane(self._mainTextArea)) self._callbacks.addSuiteTab(self) return def createMenuItems(self, invocation): """iface IContextMenuFactory; context menu handler""" menuItems = ArrayList() if invocation.getInvocationContext() == invocation.CONTEXT_SCANNER_RESULTS: menuItem = JMenuItem('Report2text') menuItem.addActionListener(GenerateReportListener(self, invocation)) menuItems.add(menuItem) return menuItems def getTabCaption(self): """iface ITab; Return the text to be displayed on the tab""" return self.EXTENSION_NAME def getUiComponent(self): """iface ITab; Passes the UI to burp""" return self._tab def focusGained(self, event): """iface FocusListener; reset color on tab focus""" self._setTabBackground(self.COLOR_BLACK) def focusLost(self, event): """iface FocusListener;""" def setReportText(self, text): """set report text""" self._setTabBackground(self.COLOR_RED) self._mainTextArea.text = text def _setTabBackground(self, color): """set tab caption background""" tabbedPane = self.getUiComponent().getParent() for idx in range(tabbedPane.getTabCount()): if tabbedPane.getTitleAt(idx) == self.EXTENSION_NAME: tabbedPane.setBackgroundAt(idx, color);