class PopupMenuBuilder(BaseMenuBuilder): """Used to build a popup menu. The created menu can later be converted to a Swing component.""" def __init__(self, label, style=NengoStyle()): BaseMenuBuilder.__init__(self, style) self.label = label self.isFirstSection = True self.menu = JPopupMenu(self.label) self.applyStyle(self.menu) if label is not None and label != "": self.addSection(label, self.style.FONT_LARGE) def addAction(self, action, section=None, index=None): assert section is not None and index is not None if section is not None: comps = self.menu.components for i, comp in enumerate(comps): if isinstance(comp, JLabel) and comp.text == section: index = i + 1 break if index is None: index = self.menu.componentCount item = JMenuItem(action.toSwingAction()) self.applyStyle(item) self.menu.insert(item, index)
class OptionsCallbackPopupMenu: # options should be a list of (name, function, [arg1, [arg2]]) tuples def __init__(self, parent, x, y, options, extraOptions=None): self.popupMenu = JPopupMenu() self.options = options self.addToMenuForOptions(options) if extraOptions: self.addToMenuForOptions(extraOptions) self.popupMenu.show(parent, x, y) def addToMenuForOptions(self, options, menu=None): if not menu: menu = self.popupMenu for option in options: if not option or not option[0]: menu.addSeparator() else: if type(option[1]) in [tuple, list]: # nested menu submenu = JMenu(option[0]) self.addToMenuForOptions(option[1], submenu) menu.add(submenu) else: menuItem = JMenuItem(option[0], actionPerformed=lambda event, option=option: self.OnChoice(option)) menu.add(menuItem) def OnChoice(self, option): if len(option) == 2: option[1]() elif len(option) == 3: option[1](option[2]) elif len(option) == 4: option[1](option[2], option[3])
def handleMouseEvent(self, event): if event.isPopupTrigger(): loadMenu = JMenuItem("Load .proto") loadMenu.addActionListener(self.tab.listener) popup = JPopupMenu() popup.add(loadMenu) if self.tab.descriptors: deserializeAsMenu = JMenu("Deserialize As...") popup.addSeparator() popup.add(deserializeAsMenu) for pb2, descriptors in self.tab.descriptors.iteritems(): subMenu = JMenu(pb2) deserializeAsMenu.add(subMenu) for name, descriptor in descriptors.iteritems(): protoMenu = JMenuItem(name) protoMenu.addActionListener( DeserializeProtoActionListener(self.tab, descriptor)) subMenu.add(protoMenu) popup.show(event.getComponent(), event.getX(), event.getY()) return
def createFormItemAddPopup(self): popup = JPopupMenu() for factory in getFactories(): if factory.getID() != "unknown": entry = JMenuItem(factory.getName()) entry.addActionListener(FormItemAddListener(self, factory)) popup.add(entry) return popup
def initializeGUI(self): # table panel of scope entries self._url_table = Table(self) table_popup = JPopupMenu(); remove_item_menu = JMenuItem(self._remove_description, actionPerformed=self.removeFromScope) table_popup.add(remove_item_menu) self._url_table.setComponentPopupMenu(table_popup) self._url_table.addMouseListener(TableMouseListener(self._url_table)) scrollPane = JScrollPane(self._url_table) # setting panel ## locate checkboxes ### for constants, see: https://portswigger.net/burp/extender/api/constant-values.html#burp.IBurpExtenderCallbacks.TOOL_PROXY self._checkboxes = { 2: JCheckBox('Target'), 4: JCheckBox('Proxy'), 8: JCheckBox('Spider'), 16: JCheckBox('Scanner'), 32: JCheckBox('Intruder'), 64: JCheckBox('Repeater'), 128: JCheckBox('Sequencer'), 1024: JCheckBox('Extender') } checkboxes_components = {0: dict(zip(range(1,len(self._checkboxes) + 1), self._checkboxes.values()))} self._label_value_regex_now_1 = JLabel("(1) Regex for the value to store: ") self._label_value_regex_now_2 = JLabel("") self._label_value_regex = JLabel("(1) New regex:") self._form_value_regex = JTextField("", 64) self._button_value_regex = JButton('Update', actionPerformed=self.updateTokenSourceRegex) self._label_header_now_1 = JLabel("(2) Header for sending the value: ") self._label_header_now_2 = JLabel("") self._label_header = JLabel("(2) New header key: ") self._form_header = JTextField("", 64) self._button_header = JButton('Update', actionPerformed=self.updateHeaderName) self._label_add_url = JLabel("Add this URL: ") self._form_add_url = JTextField("", 64) self._button_add_url = JButton('Add', actionPerformed=self.addURLDirectly) ## logate regex settings ui_components_for_settings_pane = { 0: { 0: JLabel("Local Settings:") }, 1: { 0: self._label_value_regex_now_1, 1: self._label_value_regex_now_2 }, 2: { 0: self._label_value_regex, 1: self._form_value_regex, 2: self._button_value_regex}, 3: { 0: self._label_header_now_1, 1: self._label_header_now_2 }, 4: { 0: self._label_header, 1: self._form_header, 2: self._button_header}, 5: { 0: {'item': JSeparator(JSeparator.HORIZONTAL), 'width': 3, }}, 6: { 0: JLabel("General Settings:") }, 7: { 0: self._label_add_url, 1: self._form_add_url, 2: self._button_add_url}, 8: { 0: JLabel("Use this extender in:"), 1: {'item': self.compose_ui(checkboxes_components), 'width': 3} } } # build a split panel & set UI component self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT) self._splitpane.setResizeWeight(0.85) self._splitpane.setLeftComponent(scrollPane) self._splitpane.setRightComponent(self.compose_ui(ui_components_for_settings_pane)) self._callbacks.customizeUiComponent(self._splitpane)
def __private_init__(self, text="Property Editor", columns=None, data=None, empty=None, add_actions=True, actions=None): if not actions: actions = [] if not columns: columns = [] if data == None: data = [] if not empty: empty = [] self._text = text self.this = JFrame(text) self._table = JTable() self._dtm = DefaultTableModel(0, 0) self._dtm.setColumnIdentifiers(columns) self._table.setModel(self._dtm) self._data = data for d in data: self._dtm.addRow(d) self._pane = JScrollPane(self._table) self.this.add(self._pane) self._empty = empty self.this.addWindowListener(self) self._dtm.addTableModelListener(lambda _: self._update_model()) self.this.setLocation(PropertyEditor.NEW_WINDOW_OFFSET, PropertyEditor.NEW_WINDOW_OFFSET) if add_actions: self._popup = JPopupMenu() self._pane.setComponentPopupMenu(self._popup) inherits_popup_menu(self._pane) self._actions = actions self._actions.append( ExecutorAction('Remove Selected Rows', action=lambda e: self._remove_row())) self._actions.append( ExecutorAction('Add New Row', action=lambda e: self._add_row())) for action in self._actions: self._popup.add(action.menuitem) self.this.setForeground(Color.black) self.this.setBackground(Color.lightGray) self.this.pack() self.this.setVisible(True) self.this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE) return self
def __init__(self, case, node): JPopupMenu.__init__(self, "options") #self.path = path self.node = node self.case = case if case: self.__addViewCaseAction() else: print "Debug: case not found" if node: self.__addToSourceAction() self.__addWriteMetricsAction() else: print "Debug: node not found"
def main(*args): menu = JPopupMenu() ep = ToolsLocator.getExtensionPointManager().get("View_TocActions") layer = gvsig.currentLayer() tocItem = TocItemLeaf(None, layer.getName(), layer.getShapeType()) for x in ep.iterator(): action = x.create() print "action", action continue if action.isVisible(tocItem, (layer, )): print action menu.add(MenuItem(action, layer, tocItem)) else: print "*** else:", action
def initTabs(self): # ## init autorize tabs # self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) colorsMenu = JMenu("Paint") redMenu = JMenuItem("Red") noneMenu = JMenuItem("None") greenMenu = JMenuItem("Green") redMenu.addActionListener(paintChange(self, "Red")) noneMenu.addActionListener(paintChange(self, None)) greenMenu.addActionListener(paintChange(self, "Green")) colorsMenu.add(redMenu) colorsMenu.add(noneMenu) colorsMenu.add(greenMenu) self.menu = JPopupMenu("Popup") self.menu.add(colorsMenu) self.tabs = JTabbedPane() self.tabs.addTab("Request", self._requestViewer.getComponent()) self.tabs.addTab("Response", self._responseViewer.getComponent()) self.tabs.addTab("Vulnerability", self.pnl) self.tabs.addTab("Project Settings", self.projectSettings) self.tabs.setSelectedIndex(2) self._splitpane.setRightComponent(self.tabs)
def __init__(self, label=None): JPanel.__init__(self) self.addMouseListener(self) self.addMouseWheelListener(self) self.addMouseMotionListener(self) self.hover = False self.min_width = 20 self.min_height = 20 self.resize_border = 20 self.max_show_dim = 30 # The maximum number of display dimensions to show in the popup menu self.setSize(100, 50) self.border = self.default_border self.popup = JPopupMenu() self.popup.add(JMenuItem('hide', actionPerformed=self.hideme)) self.show_label = False self.label = label self.label_offset = 0 if self.label is not None: self.show_label = True self.popup.add(JPopupMenu.Separator()) self.popup_label = JCheckBoxMenuItem('label', self.show_label, actionPerformed=self.toggle_label) self.popup.add(self.popup_label) self.label_height = 15 self.update_label() else: self.label_height = 0
def createPopupMenu(itemNames, itemFunctions): """Creates a new popup menu, which can then be shown over a component on a mouse event. To use this function, first create a Python sequence whose entries are strings, and another sequence whose entries are function objects. The strings will be the items that are displayed in your popup menu, and when an item is clicked, its corresponding function will be run. Passing in a function of None will cause a separator line to appear in the popup menu, and the corresponding string will not be displayed. Your functions must accept an event object as an argument. See also: Functions. It is best to have the menu object created only once via an application specific library function. Then, call the show(event) function on both the mousePressed and mouseReleased events on your component. The reason for this is that different operating systems (Windows, Linux, MacOS) differ in when they like to show the popup menu. The show(event) function detects when the right time is to show itself, either on mouse press or release. See the examples for more. Args: itemNames (list[str]): A list of names to create popup menu items with. itemFunctions (list[object]): A list of functions to match up with the names. Returns: JPopupMenu: The javax.swing.JPopupMenu that was created. """ print(itemNames, itemFunctions) return JPopupMenu()
def set_context_menu(self, component, scanner_issue): self.context_menu = JPopupMenu() repeater = JMenuItem("Send to Repeater") repeater.addActionListener(PopupListener(scanner_issue, self.callbacks)) intruder = JMenuItem("Send to Intruder") intruder.addActionListener(PopupListener(scanner_issue, self.callbacks)) hunt = JMenuItem("Send to HUNT") self.context_menu.add(repeater) self.context_menu.add(intruder) context_menu_listener = ContextMenuListener(component, self.context_menu) component.addMouseListener(context_menu_listener)
def __init__(self, parent, x, y, options, extraOptions=None): self.popupMenu = JPopupMenu() self.options = options self.addToMenuForOptions(options) if extraOptions: self.addToMenuForOptions(extraOptions) self.popupMenu.show(parent, x, y)
def initTabs(self): # ## init autorize tabs # self.logTable = Table(self) self.logTable.setAutoCreateRowSorter(True) tableWidth = self.logTable.getPreferredSize().width self.logTable.getColumn("ID").setPreferredWidth(Math.round(tableWidth / 50 * 2)) self.logTable.getColumn("URL").setPreferredWidth(Math.round(tableWidth / 50 * 24)) self.logTable.getColumn("Orig. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Modif. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Unauth. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Authorization Enforcement Status").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Authorization Unauth. Status").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._splitpane.setResizeWeight(1) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) self.scrollPane.getVerticalScrollBar().addAdjustmentListener(autoScrollListener(self)) self.menuES0 = JCheckBoxMenuItem(self._enfocementStatuses[0],True) self.menuES1 = JCheckBoxMenuItem(self._enfocementStatuses[1],True) self.menuES2 = JCheckBoxMenuItem(self._enfocementStatuses[2],True) self.menuES0.addItemListener(menuTableFilter(self)) self.menuES1.addItemListener(menuTableFilter(self)) self.menuES2.addItemListener(menuTableFilter(self)) copyURLitem = JMenuItem("Copy URL"); copyURLitem.addActionListener(copySelectedURL(self)) self.menu = JPopupMenu("Popup") self.menu.add(copyURLitem) self.menu.add(self.menuES0) self.menu.add(self.menuES1) self.menu.add(self.menuES2) self.tabs = JTabbedPane() self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self._originalrequestViewer = self._callbacks.createMessageEditor(self, False) self._originalresponseViewer = self._callbacks.createMessageEditor(self, False) self._unauthorizedrequestViewer = self._callbacks.createMessageEditor(self, False) self._unauthorizedresponseViewer = self._callbacks.createMessageEditor(self, False) self.tabs.addTab("Modified Request", self._requestViewer.getComponent()) self.tabs.addTab("Modified Response", self._responseViewer.getComponent()) self.tabs.addTab("Original Request", self._originalrequestViewer.getComponent()) self.tabs.addTab("Original Response", self._originalresponseViewer.getComponent()) self.tabs.addTab("Unauthenticated Request", self._unauthorizedrequestViewer.getComponent()) self.tabs.addTab("Unauthenticated Response", self._unauthorizedresponseViewer.getComponent()) self.tabs.addTab("Configuration", self.pnl) self.tabs.setSelectedIndex(6) self._splitpane.setRightComponent(self.tabs)
def __init__(self, label, style=NengoStyle()): BaseMenuBuilder.__init__(self, style) self.label = label self.isFirstSection = True self.menu = JPopupMenu(self.label) self.applyStyle(self.menu) if label is not None and label != "": self.addSection(label, self.style.FONT_LARGE)
def actionPerformed(self, event): messages = self.browser.getSelectedMessages() numMessages = messages.size() if numMessages == 0: self.browser.showInformationDialog("No messages selected") return if numMessages > 1: self.browser.showInformationDialog("%d messages selected, choose one" % numMessages) return message = messages.get(0) replyToId = message.getJMSMessageID() replyToQueue0 = message.getJMSReplyTo() if replyToQueue0 != None: replyToQueue0 = replyToQueue0.getQueueName() p = Pattern.compile("[^\\s:/]+://[^\\s:/]*/([^\\s:/?]+)\\??.*") m = p.matcher(replyToQueue0) if m.matches(): replyToQueue0 = m.group(1) else: replyToQueue0 = None dNode = self.browser.getBrowserTree().getFirstSelectedDestinationNode() hNode = self.browser.getBrowserTree().getSelectedHermesNode() if dNode == None or hNode == None: self.browser.showInformationDialog("Unknown destination, select destination queue") return hermes = hNode.getHermes() replyToQueue1 = dNode.getDestinationName() replyToDomain = dNode.getDomain() if replyToQueue0 == None and replyToQueue1 == None: self.browser.showInformationDialog("Unknown destination, select destination queue") return # show menu if replyToQueue0 != None and replyToQueue1 != None and replyToQueue0 != replyToQueue1: menu = JPopupMenu() q0item = JMenuItem(replyToQueue0) q0item.addActionListener(MenuItemHandler(self, hermes, replyToId, replyToQueue0, replyToDomain)) menu.add(q0item) q1item = JMenuItem(replyToQueue1) q1item.addActionListener(MenuItemHandler(self, hermes, replyToId, replyToQueue1, replyToDomain)) menu.add(q1item) menu.show(self.button, 0, self.button.getHeight()) return # show new message dialog else: if replyToQueue0 != None: replyToQueue = replyToQueue0 else: replyToQueue = replyToQueue1 self.replyTo(hermes, replyToId, replyToQueue, replyToDomain)
def initTabs(self): # ## init autorize tabs # self.logTable = Table(self) self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._splitpane.setResizeWeight(1) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) self.scrollPane.getVerticalScrollBar().addAdjustmentListener( autoScrollListener(self)) copyURLitem = JMenuItem("Copy URL") copyURLitem.addActionListener(copySelectedURL(self)) self.menu = JPopupMenu("Popup") self.menu.add(copyURLitem) self.tabs = JTabbedPane() self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self._originalrequestViewer = self._callbacks.createMessageEditor( self, False) self._originalresponseViewer = self._callbacks.createMessageEditor( self, False) self.tabs.addTab("Modified Request", self._requestViewer.getComponent()) self.tabs.addTab("Modified Response", self._responseViewer.getComponent()) self.tabs.addTab("Original Request", self._originalrequestViewer.getComponent()) self.tabs.addTab("Original Response", self._originalresponseViewer.getComponent()) self.tabs.addTab("Configuration", self.pnl) self.tabs.setSelectedIndex(4) self._splitpane.setRightComponent(self.tabs)
def show(self, component, onChange): self.__onChange = onChange menu = JPopupMenu() jcalendar = JCalendar() jcalendar.addDateListener(self) menu.add(jcalendar) menu.show(component, 0, component.getY() + int(component.getSize().getHeight()))
def createPopupMenu(itemNames, itemFunctions): """Creates a new popup menu, which can then be shown over a component on a mouse event. Args: itemNames (list[str]): A list of names to create popup menu items with. itemFunctions (list[object]): A list of functions to match up with the names. Returns: JPopupMenu: The javax.swing.JPopupMenu that was created. """ print(itemNames, itemFunctions) return JPopupMenu()
def PUmenu(self): #----------------------------------------------------------------------- # Name: MenuItem() # Role: Return a JMenuItem with the given text, with actionPerformed set #----------------------------------------------------------------------- def MenuItem(text): return JMenuItem(text, actionPerformed=self.actionPerformed) popup = JPopupMenu() popup.add(MenuItem('Spam')) popup.add(MenuItem('Eggs')) popup.add(MenuItem('Bacon')) return popup
def initTabs(self): # ## init autorize tabs # self.logTable = Table(self) self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._splitpane.setResizeWeight(1) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) self.scrollPane.getVerticalScrollBar().addAdjustmentListener(autoScrollListener(self)) self.menuES0 = JCheckBoxMenuItem(self._enfocementStatuses[0],True) self.menuES1 = JCheckBoxMenuItem(self._enfocementStatuses[1],True) self.menuES2 = JCheckBoxMenuItem(self._enfocementStatuses[2],True) self.menuES0.addItemListener(menuTableFilter(self)) self.menuES1.addItemListener(menuTableFilter(self)) self.menuES2.addItemListener(menuTableFilter(self)) copyURLitem = JMenuItem("Copy URL"); copyURLitem.addActionListener(copySelectedURL(self)) self.menu = JPopupMenu("Popup") self.menu.add(copyURLitem) self.menu.add(self.menuES0) self.menu.add(self.menuES1) self.menu.add(self.menuES2) self.tabs = JTabbedPane() self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self._originalrequestViewer = self._callbacks.createMessageEditor(self, False) self._originalresponseViewer = self._callbacks.createMessageEditor(self, False) self.tabs.addTab("Modified Request", self._requestViewer.getComponent()) self.tabs.addTab("Modified Response", self._responseViewer.getComponent()) self.tabs.addTab("Original Request", self._originalrequestViewer.getComponent()) self.tabs.addTab("Original Response", self._originalresponseViewer.getComponent()) self.tabs.addTab("Configuration", self.pnl) self.tabs.setSelectedIndex(4) self._splitpane.setRightComponent(self.tabs)
class TreePopup(JPopupMenu): ''' Context menu for the tree case panel ''' # # Constructor # def __init__(self, case, node): JPopupMenu.__init__(self, "options") #self.path = path self.node = node self.case = case if case: self.__addViewCaseAction() else: print "Debug: case not found" if node: self.__addToSourceAction() self.__addWriteMetricsAction() else: print "Debug: node not found"
def __init__(self,view): JPanel.__init__(self) self.view=view self.background=Color.white self.layout=BorderLayout() self.popup=JPopupMenu() self.popup_items={} self.add(self.make_controls(),BorderLayout.SOUTH) data,title=self.extract_data() self.table=JTable(DefaultTableModel(data,title)) scroll=JScrollPane(self.table) self.add(scroll) scroll.addMouseListener(self) self.table.tableHeader.addMouseListener(self) self.table.addMouseListener(self) self.fileChooser=JFileChooser() self.fileChooser.setFileFilter(CSVFilter()) self.fileChooser.setSelectedFile(File('%s.csv'%self.view.network.name))
def initVulnerabilityTab(self): # ## init vulnerability tab # nameLabel = JLabel("Vulnerability Name:") nameLabel.setBounds(10, 10, 140, 30) self.addButton = JButton("Add",actionPerformed=self.addVuln) self.addButton.setBounds(10, 500, 100, 30) rmVulnButton = JButton("Remove",actionPerformed=self.rmVuln) rmVulnButton.setBounds(465, 500, 100, 30) mitigationLabel = JLabel("Mitigation:") mitigationLabel.setBounds(10, 290, 150, 30) addSSBtn = JButton("Add SS",actionPerformed=self.addSS) addSSBtn.setBounds(750, 40, 110, 30) deleteSSBtn = JButton("Remove SS",actionPerformed=self.removeSS) deleteSSBtn.setBounds(750, 75, 110, 30) piclistLabel = JLabel("Images list:") piclistLabel.setBounds(580, 10, 140, 30) self.screenshotsList = DefaultListModel() self.ssList = JList(self.screenshotsList) self.ssList.setBounds(580, 40, 150, 250) self.ssList.addListSelectionListener(ssChangedHandler(self)) self.ssList.setBorder(BorderFactory.createLineBorder(Color.GRAY)) previewPicLabel = JLabel("Selected image preview: (click to open in image viewer)") previewPicLabel.setBounds(580, 290, 500, 30) copyImgMenu = JMenuItem("Copy") copyImgMenu.addActionListener(copyImg(self)) self.imgMenu = JPopupMenu("Popup") self.imgMenu.add(copyImgMenu) self.firstPic = JLabel() self.firstPic.setBorder(BorderFactory.createLineBorder(Color.GRAY)) self.firstPic.setBounds(580, 320, 550, 400) self.firstPic.addMouseListener(imageClicked(self)) self.vulnName = JTextField("") self.vulnName.getDocument().addDocumentListener(vulnTextChanged(self)) self.vulnName.setBounds(140, 10, 422, 30) sevirities = ["Unclassified", "Critical","High","Medium","Low"] self.threatLevel = JComboBox(sevirities); self.threatLevel.setBounds(140, 45, 140, 30) colors = ["Color:", "Green", "Red"] self.colorCombo = JComboBox(colors); self.colorCombo.setBounds(465, 45, 100, 30) self.colorCombo severityLabel = JLabel("Threat Level:") severityLabel.setBounds(10, 45, 100, 30) descriptionLabel = JLabel("Description:") descriptionLabel.setBounds(10, 80, 100, 30) self.descriptionString = JTextArea("", 5, 30) self.descriptionString.setWrapStyleWord(True); self.descriptionString.setLineWrap(True) self.descriptionString.setBounds(10, 110, 555, 175) descriptionStringScroll = JScrollPane(self.descriptionString) descriptionStringScroll.setBounds(10, 110, 555, 175) descriptionStringScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED) self.mitigationStr = JTextArea("", 5, 30) self.mitigationStr.setWrapStyleWord(True); self.mitigationStr.setLineWrap(True) self.mitigationStr.setBounds(10, 320, 555, 175) mitigationStrScroll = JScrollPane(self.mitigationStr) mitigationStrScroll.setBounds(10, 320, 555, 175) mitigationStrScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED) self.pnl = JPanel() self.pnl.setBounds(0, 0, 1000, 1000); self.pnl.setLayout(None); self.pnl.add(addSSBtn) self.pnl.add(piclistLabel) self.pnl.add(nameLabel) self.pnl.add(deleteSSBtn) self.pnl.add(rmVulnButton) self.pnl.add(severityLabel) self.pnl.add(mitigationLabel) self.pnl.add(descriptionLabel) self.pnl.add(previewPicLabel) self.pnl.add(mitigationStrScroll) self.pnl.add(descriptionStringScroll) self.pnl.add(self.ssList) self.pnl.add(self.firstPic) self.pnl.add(self.addButton) self.pnl.add(self.vulnName) self.pnl.add(self.threatLevel) self.pnl.add(self.colorCombo)
class GeneratorPanel(): """ Compound class that represents the burp user interface tab. It can run standalone with limited functionalities with: jython -m inql.widgets.tab """ def __init__(self, actions=[], restore=None, proxy=None, http_mutator=None, texteditor_factory=None, requests=None, stub_responses=None): self._requests = requests if requests is not None else {} self._stub_responses = stub_responses if stub_responses is not None else {} self._actions = actions self._load_headers = [] self._run_config = [['Proxy', proxy], ['Authorization Key', None], ['Load Placeholders', True], ['Generate HTML DOC', True], ['Generate Schema DOC', False], ['Generate Stub Queries', True], ['Accept Invalid SSL Certificate', True], ['Generate Cycles Report', False], ['Cycles Report Timeout', 60], ['Generate TSV', False]] self._init_config = json.loads(json.dumps(self._run_config)) self._default_config = {} for k, v in self._run_config: self._default_config[k] = v self._old_config_hash = None self._actions.insert(0, BrowserAction()) self._actions.insert( 0, ExecutorAction("Configure", lambda _: self._setup())) self._actions.insert(0, ExecutorAction("Load", self._loadurl)) self._http_mutator = http_mutator self.this = JPanel() self.this.setLayout(BorderLayout()) self._omnibar = Omnibar(hint=DEFAULT_LOAD_URL, label="Load", action=self._loadurl) self.this.add(BorderLayout.PAGE_START, self._omnibar.this) self._fileview = FileView( dir=os.getcwd(), filetree_label="Queries, Mutations and Subscriptions", texteditor_factory=texteditor_factory) self.this.add(BorderLayout.CENTER, self._fileview.this) self._fileview.addTreeListener(self._tree_listener) self._fileview.addPayloadListener(self._payload_listener) self._popup = JPopupMenu() self.this.setComponentPopupMenu(self._popup) inherits_popup_menu(self.this) for action in self._actions: self._popup.add(action.menuitem) self._state = {'runs': []} try: if restore: cfg = json.loads(restore) if 'runs' in cfg: for target, key, proxy, headers, load_placeholer, generate_html, generate_schema, generate_queries, generate_cycles, cycles_timeout, generate_tsv, accept_invalid_certificate, flag in cfg[ 'runs']: self._run(target=target, key=key, proxy=proxy, headers=headers, load_placeholer=load_placeholer, generate_html=generate_html, generate_schema=generate_schema, generate_queries=generate_queries, generate_cycles=generate_cycles, cycles_timeout=cycles_timeout, generate_tsv=generate_tsv, accept_invalid_certificate= accept_invalid_certificate, flag=flag) self._run_config = cfg['config'] except Exception as ex: print( "Cannot Load old configuration: starting with a clean state: %s" % ex) sys.stdout.flush() self._state['config'] = self._run_config def _setup_headers(self): """ Setup Headers callback :return: None """ PropertyEditor.get_instance( text='Load Headers', columns=['Header', 'Value'], data=self._load_headers, empty=["X-New-Header", "X-New-Header-Value"]) def _setup(self): """ Setup callback :return: None """ PropertyEditor.get_instance(text="Configure InQL", columns=['Property', 'Value'], data=self._run_config, actions=[ ExecutorAction( "Setup Load Headers", lambda _: self._setup_headers()), ExecutorAction("Reset", lambda _: self._reset()) ]) def _cfg(self, key): """ :param key: the key of the configuration :return: configuration value or default if unset """ new_hash = hash(string.join([str(i) for _, i in self._run_config])) if self._old_config_hash != new_hash: self._config = {} for k, v in self._run_config: self._config[k] = v self._old_config_hash = new_hash try: return self._config[key] except KeyError: try: return self._default_config[key] except KeyError: return None def state(self): """ Tab State, used to regenerate the status after load. :return: the current status in JSON format, this will be saved in BURP preferences for later reuse """ return json.dumps(self._state) def _reset(self): """Reset configuration state""" self._state['config'] = json.loads(json.dumps(self._init_config)) self._run_config = self._state['config'] self._state['runs'] = {} def _tree_listener(self, e): """ Listen to Ftree change and act on that behalf. :param e: get current path and set the context on every action. :return: None """ try: host = [str(p) for p in e.getPath().getPath()][1] self._host = host fname = os.path.join(*[str(p) for p in e.getPath().getPath()][1:]) self._fname = fname f = open(fname, "r") payload = f.read() for action in self._actions: action.ctx(host=host, payload=payload, fname=fname) except IOError: pass def _payload_listener(self, e): """ Listen for Payload Change and change the context of every action accordingly. :param e: event change. :return: None """ try: doc = e.getDocument() payload = doc.getText(0, doc.getLength()) for action in self._actions: action.ctx(host=self._host, payload=payload, fname=self._fname) except Exception: pass def _filepicker(self): """ Run the filepicker and return if approved :return: boolean, true if approved """ fileChooser = JFileChooser() fileChooser.setCurrentDirectory(File(System.getProperty("user.home"))) result = fileChooser.showOpenDialog(self.this) isApproveOption = result == JFileChooser.APPROVE_OPTION if isApproveOption: selectedFile = fileChooser.getSelectedFile() self._omnibar.setText(selectedFile.getAbsolutePath()) return isApproveOption def _loadurl(self, evt): """ load url if present. :param evt: load url or reload itself with the same evt. :return: None """ target = self._omnibar.getText().strip() if target == DEFAULT_LOAD_URL: if self._filepicker(): self._loadurl(evt) elif target == 'about:config': self._setup() self._omnibar.reset() elif target == 'about:headers': self._setup_headers() self._omnibar.reset() elif target.startswith('http://') or target.startswith('https://'): print("Quering GraphQL schema from: %s" % target) self._run(target=target, key=self._cfg('Authorization Key'), proxy=self._cfg('Proxy'), headers=self._load_headers, load_placeholer=self._cfg('Load Placeholders'), generate_html=self._cfg('Generate HTML DOC'), generate_schema=self._cfg('Generate Schema DOC'), generate_queries=self._cfg('Generate Stub Queries'), generate_cycles=self._cfg('Generate Cycles Report'), cycles_timeout=self._cfg('Cycles Report Timeout'), generate_tsv=self._cfg('Generate TSV'), accept_invalid_certificate=self._cfg( 'Accept Invalid SSL Certificate'), flag="URL") elif not os.path.isfile(target): if self._filepicker(): self._loadurl(evt) else: print("Loading JSON schema from: %s" % target) self._run(target=target, key=self._cfg('Authorization Key'), proxy=self._cfg('Proxy'), headers=self._load_headers, load_placeholer=self._cfg('Load Placeholders'), generate_html=self._cfg('Generate HTML DOC'), generate_schema=self._cfg('Generate Schema DOC'), generate_queries=self._cfg('Generate Stub Queries'), generate_cycles=self._cfg('Generate Cycles Report'), cycles_timeout=self._cfg('Cycles Report Timeout'), generate_tsv=self._cfg('Generate TSV'), accept_invalid_certificate=self._cfg( 'Accept Invalid SSL Certificate'), flag="JSON") def _run(self, target, key, proxy, headers, load_placeholer, generate_html, generate_schema, generate_queries, generate_cycles, cycles_timeout, generate_tsv, accept_invalid_certificate, flag): """ Run the actual analysis, this method is a wrapper for the non-UI version of the tool and basically calls the main/init method by itself. :param target: target URL :param load_placeholer: load placeholder option :param generate_html: generate html option :param generate_schema: generate schema option :param generate_queries: generate queries option :param flag: "JSON" file or normal target otherwise :return: None """ self._omnibar.reset() args = { "key": key, "proxy": proxy, 'headers': headers, "detect": load_placeholer, "generate_html": generate_html, "generate_schema": generate_schema, "generate_queries": generate_queries, "generate_cycles": generate_cycles, "cycles_timeout": cycles_timeout, "cycles_streaming": False, # there is no UI to show streaming cycles. "generate_tsv": generate_tsv, "target": target if flag != "JSON" else None, "schema_json_file": target if flag == "JSON" else None, "insecure_certificate": accept_invalid_certificate, "requests": self._requests, "stub_responses": self._stub_responses } # call init method from Introspection tool if flag == 'JSON': with open(target, 'r') as f: host = os.path.splitext(os.path.basename(target))[0] self._http_mutator.set_stub_response(host, f.read()) def async_run(): init(AttrDict(args.copy())) self._state['runs'].append( (target, key, proxy, headers, load_placeholer, generate_html, generate_schema, generate_queries, generate_cycles, cycles_timeout, generate_tsv, accept_invalid_certificate, flag)) self._fileview.refresh() run_async(async_run) return def app(self, label="InQL Scanner"): frame = JFrame(label) frame.setForeground(Color.black) frame.setBackground(Color.lightGray) cp = frame.getContentPane() cp.add(self.this) frame.pack() frame.setVisible(True) frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) while frame.isVisible(): time.sleep(1)
class QatDialog(ToggleDialog): """ToggleDialog for error type selection and buttons for reviewing errors in sequence """ def __init__(self, name, iconName, tooltip, shortcut, height, app): ToggleDialog.__init__(self, name, iconName, tooltip, shortcut, height) self.app = app tools = app.tools #Main panel of the dialog mainPnl = JPanel(BorderLayout()) mainPnl.setBorder(BorderFactory.createEmptyBorder(0, 1, 1, 1)) ### First tab: errors selection and download ########################### #ComboBox with tools names self.toolsComboModel = DefaultComboBoxModel() for tool in tools: self.add_data_to_models(tool) self.toolsCombo = JComboBox(self.toolsComboModel, actionListener=ToolsComboListener(app)) renderer = ToolsComboRenderer(self.app) renderer.setPreferredSize(Dimension(20, 20)) self.toolsCombo.setRenderer(renderer) self.toolsCombo.setToolTipText( app.strings.getString("Select_a_quality_assurance_tool")) #ComboBox with categories names ("views"), of the selected tool self.viewsCombo = JComboBox(actionListener=ViewsComboListener(app)) self.viewsCombo.setToolTipText( app.strings.getString("Select_a_category_of_error")) #Popup for checks table self.checkPopup = JPopupMenu() #add favourite check self.menuItemAdd = JMenuItem( self.app.strings.getString("Add_to_favourites")) self.menuItemAdd.setIcon( ImageIcon( File.separator.join([ self.app.SCRIPTDIR, "tools", "data", "Favourites", "icons", "tool_16.png" ]))) self.menuItemAdd.addActionListener(PopupActionListener(self.app)) self.checkPopup.add(self.menuItemAdd) #remove favourite check self.menuItemRemove = JMenuItem( self.app.strings.getString("Remove_from_favourites")) self.menuItemRemove.setIcon( ImageIcon( File.separator.join([ self.app.SCRIPTDIR, "tools", "data", "Favourites", "icons", "black_tool_16.png" ]))) self.menuItemRemove.addActionListener(PopupActionListener(self.app)) self.checkPopup.add(self.menuItemRemove) #Help link for selected check self.menuItemHelp = JMenuItem(self.app.strings.getString("check_help")) self.menuItemHelp.setIcon( ImageIcon( File.separator.join( [self.app.SCRIPTDIR, "images", "icons", "info_16.png"]))) self.checkPopup.add(self.menuItemHelp) self.menuItemHelp.addActionListener(PopupActionListener(self.app)) #Table with checks of selected tool and view self.checksTable = JTable() self.iconrenderer = IconRenderer() self.iconrenderer.setHorizontalAlignment(JLabel.CENTER) scrollPane = JScrollPane(self.checksTable) self.checksTable.setFillsViewportHeight(True) tableSelectionModel = self.checksTable.getSelectionModel() tableSelectionModel.addListSelectionListener(ChecksTableListener(app)) self.checksTable.addMouseListener( ChecksTableClickListener(app, self.checkPopup, self.checksTable)) #Favourite area status indicator self.favAreaIndicator = JLabel() self.update_favourite_zone_indicator() self.favAreaIndicator.addMouseListener(FavAreaIndicatorListener(app)) #label with OSM id of the object currently edited and number of #errors still to review self.checksTextFld = JTextField("", editable=0, border=None, background=None) #checks buttons btnsIconsDir = File.separator.join([app.SCRIPTDIR, "images", "icons"]) downloadIcon = ImageIcon( File.separator.join([btnsIconsDir, "download.png"])) self.downloadBtn = JButton(downloadIcon, actionPerformed=app.on_downloadBtn_clicked, enabled=0) startIcon = ImageIcon( File.separator.join([btnsIconsDir, "start_fixing.png"])) self.startBtn = JButton(startIcon, actionPerformed=app.on_startBtn_clicked, enabled=0) self.downloadBtn.setToolTipText( app.strings.getString("Download_errors_in_this_area")) self.startBtn.setToolTipText( app.strings.getString("Start_fixing_the_selected_errors")) #tab layout panel1 = JPanel(BorderLayout(0, 1)) comboboxesPnl = JPanel(GridLayout(0, 2, 5, 0)) comboboxesPnl.add(self.toolsCombo) comboboxesPnl.add(self.viewsCombo) checksPnl = JPanel(BorderLayout(0, 1)) checksPnl.add(scrollPane, BorderLayout.CENTER) self.statsPanel = JPanel(BorderLayout(4, 0)) self.statsPanel_def_color = self.statsPanel.getBackground() self.statsPanel.add(self.checksTextFld, BorderLayout.CENTER) self.statsPanel.add(self.favAreaIndicator, BorderLayout.LINE_START) checksPnl.add(self.statsPanel, BorderLayout.PAGE_END) checksButtonsPnl = JPanel(GridLayout(0, 2, 0, 0)) checksButtonsPnl.add(self.downloadBtn) checksButtonsPnl.add(self.startBtn) panel1.add(comboboxesPnl, BorderLayout.PAGE_START) panel1.add(checksPnl, BorderLayout.CENTER) panel1.add(checksButtonsPnl, BorderLayout.PAGE_END) ### Second tab: errors fixing ########################################## #label with error stats self.errorTextFld = JTextField("", editable=0, border=None, background=None) #label with current error description self.errorDesc = JLabel("") self.errorDesc.setAlignmentX(0.5) #error buttons errorInfoBtnIcon = ImageProvider.get("info") self.errorInfoBtn = JButton( errorInfoBtnIcon, actionPerformed=app.on_errorInfoBtn_clicked, enabled=0) notErrorIcon = ImageIcon( File.separator.join([btnsIconsDir, "not_error.png"])) self.notErrorBtn = JButton( notErrorIcon, actionPerformed=app.on_falsePositiveBtn_clicked, enabled=0) ignoreIcon = ImageIcon(File.separator.join([btnsIconsDir, "skip.png"])) self.ignoreBtn = JButton(ignoreIcon, actionPerformed=app.on_ignoreBtn_clicked, enabled=0) correctedIcon = ImageIcon( File.separator.join([btnsIconsDir, "corrected.png"])) self.correctedBtn = JButton( correctedIcon, actionPerformed=app.on_correctedBtn_clicked, enabled=0) nextIcon = ImageIcon(File.separator.join([btnsIconsDir, "next.png"])) self.nextBtn = JButton(nextIcon, actionPerformed=app.on_nextBtn_clicked, enabled=0) #self.nextBtn.setMnemonic(KeyEvent.VK_RIGHT) self.errorInfoBtn.setToolTipText( app.strings.getString("open_error_info_dialog")) self.notErrorBtn.setToolTipText( app.strings.getString("flag_false_positive")) self.ignoreBtn.setToolTipText( app.strings.getString("Skip_and_don't_show_me_this_error_again")) self.correctedBtn.setToolTipText( app.strings.getString("flag_corrected_error")) self.nextBtn.setToolTipText(app.strings.getString("Go_to_next_error")) #tab layout self.panel2 = JPanel(BorderLayout()) self.panel2.add(self.errorTextFld, BorderLayout.PAGE_START) self.panel2.add(self.errorDesc, BorderLayout.CENTER) errorButtonsPanel = JPanel(GridLayout(0, 5, 0, 0)) errorButtonsPanel.add(self.errorInfoBtn) errorButtonsPanel.add(self.notErrorBtn) errorButtonsPanel.add(self.ignoreBtn) errorButtonsPanel.add(self.correctedBtn) errorButtonsPanel.add(self.nextBtn) self.panel2.add(errorButtonsPanel, BorderLayout.PAGE_END) #Layout self.tabbedPane = JTabbedPane() self.tabbedPane.addTab(self.app.strings.getString("Download"), None, panel1, self.app.strings.getString("download_tab")) mainPnl.add(self.tabbedPane, BorderLayout.CENTER) self.createLayout(mainPnl, False, None) def add_data_to_models(self, tool): """Add data of a tool to the models of the dialog components """ #tools combobox model if tool == self.app.favouritesTool: self.toolsComboModel.addElement(JSeparator()) self.toolsComboModel.addElement(tool) #views combobox model tool.viewsComboModel = DefaultComboBoxModel() for view in tool.views: tool.viewsComboModel.addElement(view.title) #checks table, one TableModel for each view, of each tool columns = [ "", self.app.strings.getString("Check"), self.app.strings.getString("Errors") ] for view in tool.views: tableRows = [] for check in view.checks: if check.icon is not None: icon = check.icon else: icon = "" errorsNumber = "" tableRows.append([icon, check.title, errorsNumber]) view.tableModel = MyTableModel(tableRows, columns) def update_favourite_zone_indicator(self): #icon if self.app.favZone is not None: self.favAreaIndicator.setIcon(self.app.favZone.icon) #tooltip messageArguments = array([self.app.favZone.name], String) formatter = MessageFormat("") formatter.applyPattern( self.app.strings.getString("favAreaIndicator_tooltip")) msg = formatter.format(messageArguments) self.favAreaIndicator.setToolTipText(msg) #status self.favAreaIndicator.setVisible(self.app.favouriteZoneStatus) def set_checksTextFld_color(self, color): """Change color of textField under checksTable """ colors = { "white": (255, 255, 255), "black": (0, 0, 0), "green": (100, 200, 0), "red": (200, 0, 0) } if color == "default": self.statsPanel.background = self.statsPanel_def_color self.checksTextFld.foreground = colors["black"] else: self.statsPanel.background = colors[color] self.checksTextFld.foreground = colors["white"] def change_selection(self, source): """Change comboboxes and checks table selections after a selection has been made by the user """ if source in ("menu", "layer", "add favourite"): self.app.selectionChangedFromMenuOrLayer = True self.toolsCombo.setSelectedItem(self.app.selectedTool) self.viewsCombo.setModel(self.app.selectedTool.viewsComboModel) self.viewsCombo.setSelectedItem(self.app.selectedView.title) self.checksTable.setModel(self.app.selectedTableModel) self.refresh_checksTable_columns_geometries() for i, c in enumerate(self.app.selectedView.checks): if c == self.app.selectedChecks[0]: break self.checksTable.setRowSelectionInterval(i, i) self.app.selectionChangedFromMenuOrLayer = False else: self.app.selectionChangedFromMenuOrLayer = False if source == "toolsCombo": self.viewsCombo.setModel(self.app.selectedTool.viewsComboModel) self.viewsCombo.setSelectedIndex(0) elif source == "viewsCombo": self.checksTable.setModel(self.app.selectedTableModel) self.refresh_checksTable_columns_geometries() if self.app.selectedView.checks != []: # favourite checks may be none self.checksTable.setRowSelectionInterval(0, 0) def refresh_checksTable_columns_geometries(self): self.checksTable.getColumnModel().getColumn(0).setCellRenderer( self.iconrenderer) self.checksTable.getColumnModel().getColumn(0).setMaxWidth(25) self.checksTable.getColumnModel().getColumn(2).setMaxWidth(60) def activate_error_tab(self, status): if status: if self.tabbedPane.getTabCount() == 1: self.tabbedPane.addTab(self.app.strings.getString("Fix"), None, self.panel2, self.app.strings.getString("fix_tab")) else: if self.tabbedPane.getTabCount() == 2: self.tabbedPane.remove(1) def update_checks_buttons(self): """This method sets the status of downloadBtn and startBtn """ #none check selected if len(self.app.selectedChecks) == 0: self.downloadBtn.setEnabled(False) self.startBtn.setEnabled(False) else: #some check selected self.downloadBtn.setEnabled(True) if len(self.app.selectedChecks) > 1: self.startBtn.setEnabled(False) else: #only one check is selected self.app.errors = self.app.selectedChecks[0].errors if self.app.errors is None or len(self.app.errors) == 0: #errors file has not been downloaded and parsed yet self.startBtn.setEnabled(False) else: #errors file has been downloaded and parsed if self.app.selectedChecks[0].toDo == 0: #all errors have been corrected self.startBtn.setEnabled(False) else: self.startBtn.setEnabled(True) #self.nextBtn.setEnabled(True) def update_error_buttons(self, mode): """This method sets the status of: ignoreBtn, falsePositiveBtn, correctedBtn, nextBtn """ if mode == "new error": status = True else: status = False if self.app.selectedChecks[0].tool.fixedFeedbackMode is None: self.correctedBtn.setEnabled(False) else: self.correctedBtn.setEnabled(status) if self.app.selectedChecks[0].tool.falseFeedbackMode is None: self.notErrorBtn.setEnabled(False) else: self.notErrorBtn.setEnabled(status) self.errorInfoBtn.setEnabled(status) self.ignoreBtn.setEnabled(status) if mode in ("reset", "review end"): self.nextBtn.setEnabled(False) elif mode in ("errors downloaded", "show stats", "new error"): self.nextBtn.setEnabled(True) def update_text_fields(self, mode, errorInfo=""): """This method updates the text in: checksTextFld, errorDesc, errorTextFld """ self.errorDesc.text = "" if mode == "review end": cheksTextColor = "green" checksText = self.app.strings.getString("All_errors_reviewed.") errorText = self.app.strings.getString("All_errors_reviewed.") elif mode == "reset": cheksTextColor = "default" checksText = "" errorText = "" elif mode == "show stats": cheksTextColor = "default" checksText = "%s %d / %s" % ( self.app.strings.getString("to_do"), self.app.selectedChecks[0].toDo, len(self.app.selectedChecks[0].errors)) #print "checks text", checksText errorText = "%s%s %d / %s" % ( errorInfo, self.app.strings.getString("to_do"), self.app.selectedChecks[0].toDo, len(self.app.selectedChecks[0].errors)) #print "error text", errorText if self.app.selectedError is not None and self.app.selectedError.desc != "": self.errorDesc.text = "<html>%s</html>" % self.app.selectedError.desc self.set_checksTextFld_color(cheksTextColor) self.checksTextFld.text = checksText self.errorTextFld.text = errorText self.update_statsPanel_status() def update_statsPanel_status(self): if self.checksTextFld.text == "" and not self.app.favouriteZoneStatus: self.statsPanel.setVisible(False) else: self.statsPanel.setVisible(True)
def __init__(self, actions=[], restore=None): self._actions = actions self._load_headers = [] self._run_config = [['Proxy', None], ['Authorization Key', None], ['Load Placeholders', True], ['Generate HTML DOC', False], ['Generate Schema DOC', False], ['Generate Stub Queries', True], ['Accept Invalid SSL Certificate', False]] self._default_config = {} for k, v in self._run_config: self._default_config[k] = v self._old_config_hash = None self._actions.append(BrowserAction()) self._actions.append( ExecutorAction("Configure", lambda _: self._setup())) self._actions.append(ExecutorAction("Load", self._loadurl)) self._actions = [a for a in reversed(self._actions)] self.this = JPanel() self.this.setLayout(BorderLayout()) self._omnibar = Omnibar(hint=DEFAULT_LOAD_URL, label="Load", action=self._loadurl) self.this.add(BorderLayout.PAGE_START, self._omnibar.this) self._fileview = FileView( dir=os.getcwd(), filetree_label="Queries, Mutations and Subscriptions", payloadview_label="Query Template") self.this.add(BorderLayout.CENTER, self._fileview.this) self._fileview.addTreeListener(self._tree_listener) self._fileview.addPayloadListener(self._payload_listener) self._popup = JPopupMenu() self.this.setComponentPopupMenu(self._popup) inherits_popup_menu(self.this) for action in self._actions: self._popup.add(action.menuitem) self._state = {'runs': []} try: if restore: cfg = json.loads(restore) for target, key, proxy, headers, load_placeholer, generate_html, generate_schema, generate_queries, accept_invalid_certificate, flag in cfg[ 'runs']: self._run( target=target, key=key, proxy=proxy, headers=headers, load_placeholer=load_placeholer, generate_html=generate_html, generate_schema=generate_schema, generate_queries=generate_queries, accept_invalid_certificate=accept_invalid_certificate, flag=flag) self._run_config = cfg['config'] except Exception as ex: print( "Cannot Load old configuration: starting with a clean state: %s" % ex) sys.stdout.flush() self._state['config'] = self._run_config
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, IContextMenuFactory): def registerExtenderCallbacks(self, callbacks): # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("Autorize") # create the log and a lock on which to synchronize when adding log entries self._log = ArrayList() self._lock = Lock() self.intercept = 0 self.initInterceptionFilters() self.initEnforcementDetector() self.initExport() self.initConfigurationTab() self.initTabs() self.initCallbacks() print "Thank you for installing Autorize v0.9 extension" print "by Barak Tawily" return def initExport(self): # ## init enforcement detector tab # exportLType = JLabel("File Type:") exportLType.setBounds(10, 10, 100, 30) exportLES = JLabel("Enforcement Statuses:") exportLES.setBounds(10, 50, 160, 30) exportFileTypes = ["HTML"] self.exportType = JComboBox(exportFileTypes) self.exportType.setBounds(100, 10, 200, 30) exportES = [ "All Statuses", "Authorization bypass!", "Authorization enforced??? (please configure enforcement detector)", "Authorization enforced!" ] self.exportES = JComboBox(exportES) self.exportES.setBounds(100, 50, 200, 30) exportLES = JLabel("Statuses:") exportLES.setBounds(10, 50, 100, 30) self.exportButton = JButton("Export", actionPerformed=self.exportToHTML) self.exportButton.setBounds(390, 25, 100, 30) self.exportPnl = JPanel() self.exportPnl.setLayout(None) self.exportPnl.setBounds(0, 0, 1000, 1000) self.exportPnl.add(exportLType) self.exportPnl.add(self.exportType) self.exportPnl.add(exportLES) self.exportPnl.add(self.exportES) self.exportPnl.add(self.exportButton) def initEnforcementDetector(self): # ## init enforcement detector tab # self.EDFP = ArrayList() self.EDCT = ArrayList() EDLType = JLabel("Type:") EDLType.setBounds(10, 10, 140, 30) EDLContent = JLabel("Content:") EDLContent.setBounds(10, 50, 140, 30) EDLabelList = JLabel("Filter List:") EDLabelList.setBounds(10, 165, 140, 30) EDStrings = [ "Finger Print: (enforced message body contains)", "Content-Length: (constant Content-Length number of enforced response)" ] self.EDType = JComboBox(EDStrings) self.EDType.setBounds(80, 10, 430, 30) self.EDText = JTextArea("", 5, 30) self.EDText.setBounds(80, 50, 300, 110) self.EDModel = DefaultListModel() self.EDList = JList(self.EDModel) self.EDList.setBounds(80, 175, 300, 110) self.EDList.setBorder(LineBorder(Color.BLACK)) self.EDAdd = JButton("Add filter", actionPerformed=self.addEDFilter) self.EDAdd.setBounds(390, 85, 120, 30) self.EDDel = JButton("Remove filter", actionPerformed=self.delEDFilter) self.EDDel.setBounds(390, 210, 120, 30) self.EDPnl = JPanel() self.EDPnl.setLayout(None) self.EDPnl.setBounds(0, 0, 1000, 1000) self.EDPnl.add(EDLType) self.EDPnl.add(self.EDType) self.EDPnl.add(EDLContent) self.EDPnl.add(self.EDText) self.EDPnl.add(self.EDAdd) self.EDPnl.add(self.EDDel) self.EDPnl.add(EDLabelList) self.EDPnl.add(self.EDList) def initInterceptionFilters(self): # ## init interception filters tab # IFStrings = [ "URL Contains: ", "Scope items only: (Content is not required)" ] self.IFType = JComboBox(IFStrings) self.IFType.setBounds(80, 10, 430, 30) self.IFModel = DefaultListModel() self.IFList = JList(self.IFModel) self.IFList.setBounds(80, 175, 300, 110) self.IFList.setBorder(LineBorder(Color.BLACK)) self.IFText = JTextArea("", 5, 30) self.IFText.setBounds(80, 50, 300, 110) IFLType = JLabel("Type:") IFLType.setBounds(10, 10, 140, 30) IFLContent = JLabel("Content:") IFLContent.setBounds(10, 50, 140, 30) IFLabelList = JLabel("Filter List:") IFLabelList.setBounds(10, 165, 140, 30) self.IFAdd = JButton("Add filter", actionPerformed=self.addIFFilter) self.IFAdd.setBounds(390, 85, 120, 30) self.IFDel = JButton("Remove filter", actionPerformed=self.delIFFilter) self.IFDel.setBounds(390, 210, 120, 30) self.filtersPnl = JPanel() self.filtersPnl.setLayout(None) self.filtersPnl.setBounds(0, 0, 1000, 1000) self.filtersPnl.add(IFLType) self.filtersPnl.add(self.IFType) self.filtersPnl.add(IFLContent) self.filtersPnl.add(self.IFText) self.filtersPnl.add(self.IFAdd) self.filtersPnl.add(self.IFDel) self.filtersPnl.add(IFLabelList) self.filtersPnl.add(self.IFList) def initConfigurationTab(self): # ## init configuration tab # self.prevent304 = JCheckBox("Prevent 304 Not Modified status code") self.prevent304.setBounds(290, 25, 300, 30) self.ignore304 = JCheckBox("Ignore 304/204 status code responses") self.ignore304.setBounds(290, 5, 300, 30) self.ignore304.setSelected(True) self.autoScroll = JCheckBox("Auto Scroll") self.autoScroll.setBounds(290, 45, 140, 30) startLabel = JLabel("Authorization checks:") startLabel.setBounds(10, 10, 140, 30) self.startButton = JButton("Autorize is off", actionPerformed=self.startOrStop) self.startButton.setBounds(160, 10, 120, 30) self.startButton.setBackground(Color(255, 100, 91, 255)) self.clearButton = JButton("Clear List", actionPerformed=self.clearList) self.clearButton.setBounds(10, 40, 100, 30) self.replaceString = JTextArea("Cookie: Insert=injected; header=here;", 5, 30) self.replaceString.setWrapStyleWord(True) self.replaceString.setLineWrap(True) self.replaceString.setBounds(10, 80, 470, 180) self.filtersTabs = JTabbedPane() self.filtersTabs.addTab("Enforcement Detector", self.EDPnl) self.filtersTabs.addTab("Interception Filters", self.filtersPnl) self.filtersTabs.addTab("Export", self.exportPnl) self.filtersTabs.setBounds(0, 280, 2000, 700) self.pnl = JPanel() self.pnl.setBounds(0, 0, 1000, 1000) self.pnl.setLayout(None) self.pnl.add(self.startButton) self.pnl.add(self.clearButton) self.pnl.add(self.replaceString) self.pnl.add(startLabel) self.pnl.add(self.autoScroll) self.pnl.add(self.ignore304) self.pnl.add(self.prevent304) self.pnl.add(self.filtersTabs) def initTabs(self): # ## init autorize tabs # self.logTable = Table(self) self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._splitpane.setResizeWeight(1) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) self.scrollPane.getVerticalScrollBar().addAdjustmentListener( autoScrollListener(self)) copyURLitem = JMenuItem("Copy URL") copyURLitem.addActionListener(copySelectedURL(self)) self.menu = JPopupMenu("Popup") self.menu.add(copyURLitem) self.tabs = JTabbedPane() self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self._originalrequestViewer = self._callbacks.createMessageEditor( self, False) self._originalresponseViewer = self._callbacks.createMessageEditor( self, False) self.tabs.addTab("Modified Request", self._requestViewer.getComponent()) self.tabs.addTab("Modified Response", self._responseViewer.getComponent()) self.tabs.addTab("Original Request", self._originalrequestViewer.getComponent()) self.tabs.addTab("Original Response", self._originalresponseViewer.getComponent()) self.tabs.addTab("Configuration", self.pnl) self.tabs.setSelectedIndex(4) self._splitpane.setRightComponent(self.tabs) def initCallbacks(self): # ## init callbacks # # customize our UI components self._callbacks.customizeUiComponent(self._splitpane) self._callbacks.customizeUiComponent(self.logTable) self._callbacks.customizeUiComponent(self.scrollPane) self._callbacks.customizeUiComponent(self.tabs) self._callbacks.customizeUiComponent(self.filtersTabs) self._callbacks.registerContextMenuFactory(self) # add the custom tab to Burp's UI self._callbacks.addSuiteTab(self) # ## Events functions # def startOrStop(self, event): if self.startButton.getText() == "Autorize is off": self.startButton.setText("Autorize is on") self.startButton.setBackground(Color.GREEN) self.intercept = 1 self._callbacks.registerHttpListener(self) else: self.startButton.setText("Autorize is off") self.startButton.setBackground(Color(255, 100, 91, 255)) self.intercept = 0 self._callbacks.removeHttpListener(self) def addEDFilter(self, event): typeName = self.EDType.getSelectedItem().split(":")[0] self.EDModel.addElement(typeName + ": " + self.EDText.getText()) def delEDFilter(self, event): index = self.EDList.getSelectedIndex() if not index == -1: self.EDModel.remove(index) def addIFFilter(self, event): typeName = self.IFType.getSelectedItem().split(":")[0] self.IFModel.addElement(typeName + ": " + self.IFText.getText()) def delIFFilter(self, event): index = self.IFList.getSelectedIndex() if not index == -1: self.IFModel.remove(index) def clearList(self, event): self._lock.acquire() self._log = ArrayList() row = self._log.size() self.fireTableRowsInserted(row, row) self._lock.release() def exportToHTML(self, event): parentFrame = JFrame() fileChooser = JFileChooser() fileChooser.setSelectedFile(File("AutorizeReprort.html")) fileChooser.setDialogTitle("Save Autorize Report") userSelection = fileChooser.showSaveDialog(parentFrame) if userSelection == JFileChooser.APPROVE_OPTION: fileToSave = fileChooser.getSelectedFile() enforcementStatusFilter = self.exportES.getSelectedItem() htmlContent = """<html><title>Autorize Report by Barak Tawily</title> <style> .datagrid table { border-collapse: collapse; text-align: left; width: 100%; } .datagrid {font: normal 12px/150% Arial, Helvetica, sans-serif; background: #fff; overflow: hidden; border: 1px solid #006699; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .datagrid table td, .datagrid table th { padding: 3px 10px; } .datagrid table thead th {background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; color:#FFFFFF; font-size: 15px; font-weight: bold; border-left: 1px solid #0070A8; } .datagrid table thead th:first-child { border: none; }.datagrid table tbody td { color: #00496B; border-left: 1px solid #E1EEF4;font-size: 12px;font-weight: normal; }.datagrid table tbody .alt td { background: #E1EEF4; color: #00496B; }.datagrid table tbody td:first-child { border-left: none; }.datagrid table tbody tr:last-child td { border-bottom: none; }.datagrid table tfoot td div { border-top: 1px solid #006699;background: #E1EEF4;} .datagrid table tfoot td { padding: 0; font-size: 12px } .datagrid table tfoot td div{ padding: 2px; }.datagrid table tfoot td ul { margin: 0; padding:0; list-style: none; text-align: right; }.datagrid table tfoot li { display: inline; }.datagrid table tfoot li a { text-decoration: none; display: inline-block; padding: 2px 8px; margin: 1px;color: #FFFFFF;border: 1px solid #006699;-webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; }.datagrid table tfoot ul.active, .datagrid table tfoot ul a:hover { text-decoration: none;border-color: #006699; color: #FFFFFF; background: none; background-color:#00557F;}div.dhtmlx_window_active, div.dhx_modal_cover_dv { position: fixed !important; } table { width: 100%; table-layout: fixed; } td { border: 1px solid #35f; overflow: hidden; text-overflow: ellipsis; } td.a { width: 13%; white-space: nowrap; } td.b { width: 9%; word-wrap: break-word; } </style> <body> <h1>Autorize Report<h1> <div class="datagrid"><table> <thead><tr><th>URL</th><th>Authorization Enforcement Status</th></tr></thead> <tbody>""" for i in range(0, self._log.size()): color = "" if self._log.get( i )._enfocementStatus == "Authorization enforced??? (please configure enforcement detector)": color = "yellow" if self._log.get(i)._enfocementStatus == "Authorization bypass!": color = "red" if self._log.get(i)._enfocementStatus == "Authorization enforced!": color = "LawnGreen" if enforcementStatusFilter == "All Statuses": htmlContent += "<tr bgcolor=\"%s\"><td><a href=\"%s\">%s</a></td><td>%s</td></tr>" % ( color, self._log.get(i)._url, self._log.get(i)._url, self._log.get(i)._enfocementStatus) else: if enforcementStatusFilter == self._log.get( i)._enfocementStatus: htmlContent += "<tr bgcolor=\"%s\"><td><a href=\"%s\">%s</a></td><td>%s</td></tr>" % ( color, self._log.get(i)._url, self._log.get(i)._url, self._log.get(i)._enfocementStatus) htmlContent += "</tbody></table></div></body></html>" f = open(fileToSave.getAbsolutePath(), 'w') f.writelines(htmlContent) f.close() # # implement IContextMenuFactory # def createMenuItems(self, invocation): responses = invocation.getSelectedMessages() if responses > 0: ret = LinkedList() requestMenuItem = JMenuItem("Send request to Autorize") cookieMenuItem = JMenuItem("Send cookie to Autorize") requestMenuItem.addActionListener( handleMenuItems(self, responses[0], "request")) cookieMenuItem.addActionListener( handleMenuItems(self, responses[0], "cookie")) ret.add(requestMenuItem) ret.add(cookieMenuItem) return (ret) return null # # implement ITab # def getTabCaption(self): return "Autorize" def getUiComponent(self): return self._splitpane # # 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 "URL" if columnIndex == 1: return "Authorization Enforcement Status" return "" def getValueAt(self, rowIndex, columnIndex): logEntry = self._log.get(rowIndex) if columnIndex == 0: return logEntry._url.toString() if columnIndex == 1: return logEntry._enfocementStatus 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() # # implement IHttpListener # def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): if self.intercept == 1: if self.prevent304.isSelected(): if messageIsRequest: requestHeaders = list( self._helpers.analyzeRequest(messageInfo).getHeaders()) newHeaders = list() found = 0 for header in requestHeaders: if not "If-None-Match:" in header and not "If-Modified-Since:" in header: newHeaders.append(header) found = 1 if found == 1: requestInfo = self._helpers.analyzeRequest(messageInfo) bodyBytes = messageInfo.getRequest()[requestInfo. getBodyOffset():] bodyStr = self._helpers.bytesToString(bodyBytes) messageInfo.setRequest( self._helpers.buildHttpMessage( newHeaders, bodyStr)) if not messageIsRequest: if not self.replaceString.getText( ) in self._helpers.analyzeRequest(messageInfo).getHeaders(): if self.ignore304.isSelected(): firstHeader = self._helpers.analyzeResponse( messageInfo.getResponse()).getHeaders()[0] if "304" in firstHeader or "204" in firstHeader: return if self.IFList.getModel().getSize() == 0: self.checkAuthorization( messageInfo, self._helpers.analyzeResponse( messageInfo.getResponse()).getHeaders()) else: urlString = str( self._helpers.analyzeRequest(messageInfo).getUrl()) for i in range(0, self.IFList.getModel().getSize()): if self.IFList.getModel().getElementAt(i).split( ":")[0] == "Scope items only": currentURL = URL(urlString) if self._callbacks.isInScope(currentURL): self.checkAuthorization( messageInfo, self._helpers.analyzeResponse( messageInfo.getResponse()). getHeaders()) if self.IFList.getModel().getElementAt(i).split( ":")[0] == "URL Contains": if self.IFList.getModel().getElementAt( i)[14:] in urlString: self.checkAuthorization( messageInfo, self._helpers.analyzeResponse( messageInfo.getResponse()). getHeaders()) return def makeRequest(self, messageInfo, message): requestURL = self._helpers.analyzeRequest(messageInfo).getUrl() return self._callbacks.makeHttpRequest( self._helpers.buildHttpService( str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https"), message) def makeMessage(self, messageInfo, removeOrNot): requestInfo = self._helpers.analyzeRequest(messageInfo) headers = requestInfo.getHeaders() if removeOrNot: headers = list(headers) removeHeaders = ArrayList() removeHeaders.add(self.replaceString.getText() [0:self.replaceString.getText().index(":")]) for header in headers[:]: for removeHeader in removeHeaders: if removeHeader in header: headers.remove(header) headers.append(self.replaceString.getText()) msgBody = messageInfo.getRequest()[requestInfo.getBodyOffset():] return self._helpers.buildHttpMessage(headers, msgBody) def checkAuthorization(self, messageInfo, originalHeaders): message = self.makeMessage(messageInfo, True) requestResponse = self.makeRequest(messageInfo, message) analyzedResponse = self._helpers.analyzeResponse( requestResponse.getResponse()) oldStatusCode = originalHeaders[0] newStatusCode = analyzedResponse.getHeaders()[0] oldContentLen = self.getContentLength(originalHeaders) newContentLen = self.getContentLength(analyzedResponse.getHeaders()) impression = "" EDFilters = self.EDModel.toArray() if oldStatusCode == newStatusCode: if oldContentLen == newContentLen: impression = "Authorization bypass!" else: impression = "Authorization enforced??? (please configure enforcement detector)" for filter in EDFilters: if str(filter).startswith("Content-Length: "): if newContentLen == filter: impression = "Authorization enforced!" if str(filter).startswith("Finger Print: "): if filter[14:] in self._helpers.bytesToString( requestResponse.getResponse() [analyzedResponse.getBodyOffset():]): impression = "Authorization enforced!" else: impression = "Authorization enforced!" self._lock.acquire() row = self._log.size() self._log.add( LogEntry(self._callbacks.saveBuffersToTempFiles(requestResponse), self._helpers.analyzeRequest(requestResponse).getUrl(), messageInfo, impression)) # same requests not include again. self.fireTableRowsInserted(row, row) self._lock.release() def getContentLength(self, analyzedResponseHeaders): for header in analyzedResponseHeaders: if "Content-Length:" in header: return header return "null" def getCookieFromMessage(self, messageInfo): headers = list( self._helpers.analyzeRequest( messageInfo.getRequest()).getHeaders()) for header in headers: if "Cookie:" in header: return header return None
def draw(self): """ init autorize tabs """ self._extender.logTable = Table(self._extender) tableWidth = self._extender.logTable.getPreferredSize().width self._extender.logTable.getColumn("ID").setPreferredWidth( Math.round(tableWidth / 50 * 2)) self._extender.logTable.getColumn("Method").setPreferredWidth( Math.round(tableWidth / 50 * 3)) self._extender.logTable.getColumn("URL").setPreferredWidth( Math.round(tableWidth / 50 * 25)) self._extender.logTable.getColumn("Orig. Length").setPreferredWidth( Math.round(tableWidth / 50 * 4)) self._extender.logTable.getColumn("Modif. Length").setPreferredWidth( Math.round(tableWidth / 50 * 4)) self._extender.logTable.getColumn("Unauth. Length").setPreferredWidth( Math.round(tableWidth / 50 * 4)) self._extender.logTable.getColumn( "Authorization Enforcement Status").setPreferredWidth( Math.round(tableWidth / 50 * 4)) self._extender.logTable.getColumn( "Authorization Unauth. Status").setPreferredWidth( Math.round(tableWidth / 50 * 4)) self._extender.tableSorter = TableRowSorter(self._extender.tableModel) rowFilter = TableRowFilter(self._extender) self._extender.tableSorter.setRowFilter(rowFilter) self._extender.logTable.setRowSorter(self._extender.tableSorter) self._extender._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._extender._splitpane.setResizeWeight(1) self._extender.scrollPane = JScrollPane(self._extender.logTable) self._extender._splitpane.setLeftComponent(self._extender.scrollPane) self._extender.scrollPane.getVerticalScrollBar().addAdjustmentListener( AutoScrollListener(self._extender)) copyURLitem = JMenuItem("Copy URL") copyURLitem.addActionListener(CopySelectedURL(self._extender)) sendRequestMenu = JMenuItem("Send Original Request to Repeater") sendRequestMenu.addActionListener( SendRequestRepeater(self._extender, self._extender._callbacks, True)) sendRequestMenu2 = JMenuItem("Send Modified Request to Repeater") sendRequestMenu2.addActionListener( SendRequestRepeater(self._extender, self._extender._callbacks, False)) sendResponseMenu = JMenuItem("Send Responses to Comparer") sendResponseMenu.addActionListener( SendResponseComparer(self._extender, self._extender._callbacks)) retestSelecteditem = JMenuItem("Retest selected request") retestSelecteditem.addActionListener( RetestSelectedRequest(self._extender)) deleteSelectedItem = JMenuItem("Delete") deleteSelectedItem.addActionListener( DeleteSelectedRequest(self._extender)) self._extender.menu = JPopupMenu("Popup") self._extender.menu.add(sendRequestMenu) self._extender.menu.add(sendRequestMenu2) self._extender.menu.add(sendResponseMenu) self._extender.menu.add(copyURLitem) self._extender.menu.add(retestSelecteditem) # self.menu.add(deleteSelectedItem) disabling this feature until bug will be fixed. message_editor = MessageEditor(self._extender) self._extender.tabs = JTabbedPane() self._extender._requestViewer = self._extender._callbacks.createMessageEditor( message_editor, False) self._extender._responseViewer = self._extender._callbacks.createMessageEditor( message_editor, False) self._extender._originalrequestViewer = self._extender._callbacks.createMessageEditor( message_editor, False) self._extender._originalresponseViewer = self._extender._callbacks.createMessageEditor( message_editor, False) self._extender._unauthorizedrequestViewer = self._extender._callbacks.createMessageEditor( message_editor, False) self._extender._unauthorizedresponseViewer = self._extender._callbacks.createMessageEditor( message_editor, False) self._extender.tabs.addTab( "Modified Request", self._extender._requestViewer.getComponent()) self._extender.tabs.addTab( "Modified Response", self._extender._responseViewer.getComponent()) self._extender.tabs.addTab( "Original Request", self._extender._originalrequestViewer.getComponent()) self._extender.tabs.addTab( "Original Response", self._extender._originalresponseViewer.getComponent()) self._extender.tabs.addTab( "Unauthenticated Request", self._extender._unauthorizedrequestViewer.getComponent()) self._extender.tabs.addTab( "Unauthenticated Response", self._extender._unauthorizedresponseViewer.getComponent()) self._extender.tabs.addTab("Configuration", self._extender.pnl) self._extender.tabs.setSelectedIndex(6) self._extender._splitpane.setRightComponent(self._extender.tabs)
def createToCContextMenu(mapContext, selectedLayer): # TOC.java menu = JPopupMenu() ep = ToolsLocator.getExtensionPointManager().get("View_TocActions") from org.gvsig.app.project.documents.view.toc.actions import ZoomAlTemaTocMenuEntry #from org.gvsig.app.project.documents.view.ViewManager import ContextMenuActionAdapterToExtensionBuilder #ep.append("ZoomAlTema", "", ZoomAlTemaTocMenuEntry()) tocItem = TocItemLeaf(None, selectedLayer.getName(),selectedLayer.getShapeType()) nodeValue = DefaultMutableTreeNode(tocItem) #menu = FPopupMenu(mapContext, nodeValue) #return menu activesLayers = mapContext.getLayers().getActives() actions = [] for epx in ep.iterator(): action = epx.create() actions.append([action,action.getGroupOrder(), action.getGroup(), action.getOrder()]) sortedActions = sorted(actions, key = lambda x: (x[1], x[2],x[3])) group = None z = ZoomAlTemaTocMenuEntry() z.setMapContext(mapContext) zitem = LayerMenuItem(z, selectedLayer,tocItem, mapContext) menu.add(zitem) menu.addSeparator() for actionList in sortedActions: action = actionList[0] if action.isVisible(tocItem, activesLayers): #(layer,)): if group == None: pass elif group != action.getGroup(): menu.addSeparator() group = action.getGroup() if isinstance(action, AbstractTocContextMenuAction): action.setMapContext(mapContext) if action.isEnabled(tocItem, activesLayers): newItem = LayerMenuItem(action, selectedLayer, tocItem, mapContext) menu.add(newItem) else: newItem = LayerMenuItem(action, selectedLayer, tocItem, mapContext) newItem.setEnabled(False) menu.add(newItem) return menu
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, IContextMenuFactory): def registerExtenderCallbacks(self, callbacks): # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("Autorize") # create the log and a lock on which to synchronize when adding log entries self._log = ArrayList() self._lock = Lock() self._enfocementStatuses = ["Authorization bypass!","Authorization enforced??? (please configure enforcement detector)","Authorization enforced!"] self.intercept = 0 self.initInterceptionFilters() self.initEnforcementDetector() self.initEnforcementDetectorUnauthorized() self.initExport() self.initConfigurationTab() self.initTabs() self.initCallbacks() self.currentRequestNumber = 1 print "Thank you for installing Autorize v0.12 extension" print "Created by Barak Tawily" print "Contributors: Barak Tawily, Federico Dotta" print "\nGithub:\nhttps://github.com/Quitten/Autorize" return def initExport(self): # ## init enforcement detector tab # exportLType = JLabel("File Type:") exportLType.setBounds(10, 10, 100, 30) exportLES = JLabel("Enforcement Statuses:") exportLES.setBounds(10, 50, 160, 30) exportFileTypes = ["HTML","CSV"] self.exportType = JComboBox(exportFileTypes) self.exportType.setBounds(100, 10, 200, 30) exportES = ["All Statuses", self._enfocementStatuses[0], self._enfocementStatuses[1], self._enfocementStatuses[2]] self.exportES = JComboBox(exportES) self.exportES.setBounds(100, 50, 200, 30) exportLES = JLabel("Statuses:") exportLES.setBounds(10, 50, 100, 30) self.exportButton = JButton("Export",actionPerformed=self.export) self.exportButton.setBounds(390, 25, 100, 30) self.exportPnl = JPanel() self.exportPnl.setLayout(None); self.exportPnl.setBounds(0, 0, 1000, 1000); self.exportPnl.add(exportLType) self.exportPnl.add(self.exportType) self.exportPnl.add(exportLES) self.exportPnl.add(self.exportES) self.exportPnl.add(self.exportButton) def initEnforcementDetector(self): # ## init enforcement detector tab # # These two variable appears to be unused... self.EDFP = ArrayList() self.EDCT = ArrayList() EDLType = JLabel("Type:") EDLType.setBounds(10, 10, 140, 30) EDLContent = JLabel("Content:") EDLContent.setBounds(10, 50, 140, 30) EDLabelList = JLabel("Filter List:") EDLabelList.setBounds(10, 165, 140, 30) EDStrings = ["Headers (simple string): (enforced message headers contains)", "Headers (regex): (enforced messege headers contains)", "Body (simple string): (enforced messege body contains)", "Body (regex): (enforced messege body contains)", "Full request (simple string): (enforced messege contains)", "Full request (regex): (enforced messege contains)", "Content-Length: (constant Content-Length number of enforced response)"] self.EDType = JComboBox(EDStrings) self.EDType.setBounds(80, 10, 430, 30) self.EDText = JTextArea("", 5, 30) self.EDText.setBounds(80, 50, 300, 110) self.EDModel = DefaultListModel(); self.EDList = JList(self.EDModel); self.EDList.setBounds(80, 175, 300, 110) self.EDList.setBorder(LineBorder(Color.BLACK)) self.EDAdd = JButton("Add filter",actionPerformed=self.addEDFilter) self.EDAdd.setBounds(390, 85, 120, 30) self.EDDel = JButton("Remove filter",actionPerformed=self.delEDFilter) self.EDDel.setBounds(390, 210, 120, 30) self.EDPnl = JPanel() self.EDPnl.setLayout(None); self.EDPnl.setBounds(0, 0, 1000, 1000); self.EDPnl.add(EDLType) self.EDPnl.add(self.EDType) self.EDPnl.add(EDLContent) self.EDPnl.add(self.EDText) self.EDPnl.add(self.EDAdd) self.EDPnl.add(self.EDDel) self.EDPnl.add(EDLabelList) self.EDPnl.add(self.EDList) def initEnforcementDetectorUnauthorized(self): # ## init enforcement detector tab # EDLType = JLabel("Type:") EDLType.setBounds(10, 10, 140, 30) EDLContent = JLabel("Content:") EDLContent.setBounds(10, 50, 140, 30) EDLabelList = JLabel("Filter List:") EDLabelList.setBounds(10, 165, 140, 30) EDStrings = ["Headers (simple string): (enforced message headers contains)", "Headers (regex): (enforced messege headers contains)", "Body (simple string): (enforced messege body contains)", "Body (regex): (enforced messege body contains)", "Full request (simple string): (enforced messege contains)", "Full request (regex): (enforced messege contains)", "Content-Length: (constant Content-Length number of enforced response)"] self.EDTypeUnauth = JComboBox(EDStrings) self.EDTypeUnauth.setBounds(80, 10, 430, 30) self.EDTextUnauth = JTextArea("", 5, 30) self.EDTextUnauth.setBounds(80, 50, 300, 110) self.EDModelUnauth = DefaultListModel(); self.EDListUnauth = JList(self.EDModelUnauth); self.EDListUnauth.setBounds(80, 175, 300, 110) self.EDListUnauth.setBorder(LineBorder(Color.BLACK)) self.EDAddUnauth = JButton("Add filter",actionPerformed=self.addEDFilterUnauth) self.EDAddUnauth.setBounds(390, 85, 120, 30) self.EDDelUnauth = JButton("Remove filter",actionPerformed=self.delEDFilterUnauth) self.EDDelUnauth.setBounds(390, 210, 120, 30) self.EDPnlUnauth = JPanel() self.EDPnlUnauth.setLayout(None); self.EDPnlUnauth.setBounds(0, 0, 1000, 1000); self.EDPnlUnauth.add(EDLType) self.EDPnlUnauth.add(self.EDTypeUnauth) self.EDPnlUnauth.add(EDLContent) self.EDPnlUnauth.add(self.EDTextUnauth) self.EDPnlUnauth.add(self.EDAddUnauth) self.EDPnlUnauth.add(self.EDDelUnauth) self.EDPnlUnauth.add(EDLabelList) self.EDPnlUnauth.add(self.EDListUnauth) def initInterceptionFilters(self): # ## init interception filters tab # IFStrings = ["Scope items only: (Content is not required)","URL Contains (simple string): ","URL Contains (regex): ","URL Not Contains (simple string): ","URL Not Contains (regex): "] self.IFType = JComboBox(IFStrings) self.IFType.setBounds(80, 10, 430, 30) self.IFModel = DefaultListModel(); self.IFList = JList(self.IFModel); self.IFList.setBounds(80, 175, 300, 110) self.IFList.setBorder(LineBorder(Color.BLACK)) self.IFText = JTextArea("", 5, 30) self.IFText.setBounds(80, 50, 300, 110) IFLType = JLabel("Type:") IFLType.setBounds(10, 10, 140, 30) IFLContent = JLabel("Content:") IFLContent.setBounds(10, 50, 140, 30) IFLabelList = JLabel("Filter List:") IFLabelList.setBounds(10, 165, 140, 30) self.IFAdd = JButton("Add filter",actionPerformed=self.addIFFilter) self.IFAdd.setBounds(390, 85, 120, 30) self.IFDel = JButton("Remove filter",actionPerformed=self.delIFFilter) self.IFDel.setBounds(390, 210, 120, 30) self.filtersPnl = JPanel() self.filtersPnl.setLayout(None); self.filtersPnl.setBounds(0, 0, 1000, 1000); self.filtersPnl.add(IFLType) self.filtersPnl.add(self.IFType) self.filtersPnl.add(IFLContent) self.filtersPnl.add(self.IFText) self.filtersPnl.add(self.IFAdd) self.filtersPnl.add(self.IFDel) self.filtersPnl.add(IFLabelList) self.filtersPnl.add(self.IFList) def initConfigurationTab(self): # ## init configuration tab # self.prevent304 = JCheckBox("Prevent 304 Not Modified status code") self.prevent304.setBounds(290, 25, 300, 30) self.ignore304 = JCheckBox("Ignore 304/204 status code responses") self.ignore304.setBounds(290, 5, 300, 30) self.ignore304.setSelected(True) self.autoScroll = JCheckBox("Auto Scroll") #self.autoScroll.setBounds(290, 45, 140, 30) self.autoScroll.setBounds(160, 40, 140, 30) self.doUnauthorizedRequest = JCheckBox("Check unauthenticated") self.doUnauthorizedRequest.setBounds(290, 45, 300, 30) self.doUnauthorizedRequest.setSelected(True) startLabel = JLabel("Authorization checks:") startLabel.setBounds(10, 10, 140, 30) self.startButton = JButton("Autorize is off",actionPerformed=self.startOrStop) self.startButton.setBounds(160, 10, 120, 30) self.startButton.setBackground(Color(255, 100, 91, 255)) self.clearButton = JButton("Clear List",actionPerformed=self.clearList) self.clearButton.setBounds(10, 40, 100, 30) self.replaceString = JTextArea("Cookie: Insert=injected; header=here;", 5, 30) self.replaceString.setWrapStyleWord(True); self.replaceString.setLineWrap(True) self.replaceString.setBounds(10, 80, 470, 180) self.filtersTabs = JTabbedPane() self.filtersTabs.addTab("Enforcement Detector", self.EDPnl) self.filtersTabs.addTab("Detector Unauthenticated", self.EDPnlUnauth) self.filtersTabs.addTab("Interception Filters", self.filtersPnl) self.filtersTabs.addTab("Export", self.exportPnl) self.filtersTabs.setBounds(0, 280, 2000, 700) self.pnl = JPanel() self.pnl.setBounds(0, 0, 1000, 1000); self.pnl.setLayout(None); self.pnl.add(self.startButton) self.pnl.add(self.clearButton) self.pnl.add(self.replaceString) self.pnl.add(startLabel) self.pnl.add(self.autoScroll) self.pnl.add(self.ignore304) self.pnl.add(self.prevent304) self.pnl.add(self.doUnauthorizedRequest) self.pnl.add(self.filtersTabs) def initTabs(self): # ## init autorize tabs # self.logTable = Table(self) self.logTable.setAutoCreateRowSorter(True) tableWidth = self.logTable.getPreferredSize().width self.logTable.getColumn("ID").setPreferredWidth(Math.round(tableWidth / 50 * 2)) self.logTable.getColumn("URL").setPreferredWidth(Math.round(tableWidth / 50 * 24)) self.logTable.getColumn("Orig. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Modif. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Unauth. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Authorization Enforcement Status").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Authorization Unauth. Status").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._splitpane.setResizeWeight(1) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) self.scrollPane.getVerticalScrollBar().addAdjustmentListener(autoScrollListener(self)) self.menuES0 = JCheckBoxMenuItem(self._enfocementStatuses[0],True) self.menuES1 = JCheckBoxMenuItem(self._enfocementStatuses[1],True) self.menuES2 = JCheckBoxMenuItem(self._enfocementStatuses[2],True) self.menuES0.addItemListener(menuTableFilter(self)) self.menuES1.addItemListener(menuTableFilter(self)) self.menuES2.addItemListener(menuTableFilter(self)) copyURLitem = JMenuItem("Copy URL"); copyURLitem.addActionListener(copySelectedURL(self)) self.menu = JPopupMenu("Popup") self.menu.add(copyURLitem) self.menu.add(self.menuES0) self.menu.add(self.menuES1) self.menu.add(self.menuES2) self.tabs = JTabbedPane() self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self._originalrequestViewer = self._callbacks.createMessageEditor(self, False) self._originalresponseViewer = self._callbacks.createMessageEditor(self, False) self._unauthorizedrequestViewer = self._callbacks.createMessageEditor(self, False) self._unauthorizedresponseViewer = self._callbacks.createMessageEditor(self, False) self.tabs.addTab("Modified Request", self._requestViewer.getComponent()) self.tabs.addTab("Modified Response", self._responseViewer.getComponent()) self.tabs.addTab("Original Request", self._originalrequestViewer.getComponent()) self.tabs.addTab("Original Response", self._originalresponseViewer.getComponent()) self.tabs.addTab("Unauthenticated Request", self._unauthorizedrequestViewer.getComponent()) self.tabs.addTab("Unauthenticated Response", self._unauthorizedresponseViewer.getComponent()) self.tabs.addTab("Configuration", self.pnl) self.tabs.setSelectedIndex(6) self._splitpane.setRightComponent(self.tabs) def initCallbacks(self): # ## init callbacks # # customize our UI components self._callbacks.customizeUiComponent(self._splitpane) self._callbacks.customizeUiComponent(self.logTable) self._callbacks.customizeUiComponent(self.scrollPane) self._callbacks.customizeUiComponent(self.tabs) self._callbacks.customizeUiComponent(self.filtersTabs) self._callbacks.registerContextMenuFactory(self) # add the custom tab to Burp's UI self._callbacks.addSuiteTab(self) # ## Events functions # def startOrStop(self, event): if self.startButton.getText() == "Autorize is off": self.startButton.setText("Autorize is on") self.startButton.setBackground(Color.GREEN) self.intercept = 1 self._callbacks.registerHttpListener(self) else: self.startButton.setText("Autorize is off") self.startButton.setBackground(Color(255, 100, 91, 255)) self.intercept = 0 self._callbacks.removeHttpListener(self) def addEDFilter(self, event): typeName = self.EDType.getSelectedItem().split(":")[0] self.EDModel.addElement(typeName + ": " + self.EDText.getText()) def delEDFilter(self, event): index = self.EDList.getSelectedIndex(); if not index == -1: self.EDModel.remove(index); def addEDFilterUnauth(self, event): typeName = self.EDTypeUnauth.getSelectedItem().split(":")[0] self.EDModelUnauth.addElement(typeName + ": " + self.EDTextUnauth.getText()) def delEDFilterUnauth(self, event): index = self.EDListUnauth.getSelectedIndex(); if not index == -1: self.EDModelUnauth.remove(index); def addIFFilter(self, event): typeName = self.IFType.getSelectedItem().split(":")[0] self.IFModel.addElement(typeName + ": " + self.IFText.getText()) def delIFFilter(self, event): index = self.IFList.getSelectedIndex(); if not index == -1: self.IFModel.remove(index); def clearList(self, event): self._lock.acquire() oldSize = self._log.size() self._log.clear() self.fireTableRowsDeleted(0, oldSize - 1) self._lock.release() def export(self, event): if self.exportType.getSelectedItem() == "HTML": self.exportToHTML() else: self.exportToCSV() def exportToCSV(self): parentFrame = JFrame() fileChooser = JFileChooser() fileChooser.setSelectedFile(File("AutorizeReprort.csv")); fileChooser.setDialogTitle("Save Autorize Report") userSelection = fileChooser.showSaveDialog(parentFrame) if userSelection == JFileChooser.APPROVE_OPTION: fileToSave = fileChooser.getSelectedFile() enforcementStatusFilter = self.exportES.getSelectedItem() csvContent = "id\tURL\tOriginal length\tModified length\tUnauthorized length\tAuthorization Enforcement Status\tAuthorization Unauthenticated Status\n" for i in range(0,self._log.size()): if enforcementStatusFilter == "All Statuses": csvContent += "%d\t%s\t%d\t%d\t%d\t%s\t%s\n" % (self._log.get(i)._id,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, self._log.get(i)._enfocementStatus, self._log.get(i)._enfocementStatusUnauthorized) else: if (enforcementStatusFilter == self._log.get(i)._enfocementStatus) or (enforcementStatusFilter == self._log.get(i)._enfocementStatusUnauthorized): csvContent += "%d\t%s\t%d\t%d\t%d\t%s\t%s\n" % (self._log.get(i)._id,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, self._log.get(i)._enfocementStatus, self._log.get(i)._enfocementStatusUnauthorized) f = open(fileToSave.getAbsolutePath(), 'w') f.writelines(csvContent) f.close() def exportToHTML(self): parentFrame = JFrame() fileChooser = JFileChooser() fileChooser.setSelectedFile(File("AutorizeReprort.html")); fileChooser.setDialogTitle("Save Autorize Report") userSelection = fileChooser.showSaveDialog(parentFrame) if userSelection == JFileChooser.APPROVE_OPTION: fileToSave = fileChooser.getSelectedFile() enforcementStatusFilter = self.exportES.getSelectedItem() htmlContent = """<html><title>Autorize Report by Barak Tawily</title> <style> .datagrid table { border-collapse: collapse; text-align: left; width: 100%; } .datagrid {font: normal 12px/150% Arial, Helvetica, sans-serif; background: #fff; overflow: hidden; border: 1px solid #006699; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .datagrid table td, .datagrid table th { padding: 3px 10px; } .datagrid table thead th {background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; color:#FFFFFF; font-size: 15px; font-weight: bold; border-left: 1px solid #0070A8; } .datagrid table thead th:first-child { border: none; }.datagrid table tbody td { color: #00496B; border-left: 1px solid #E1EEF4;font-size: 12px;font-weight: normal; }.datagrid table tbody .alt td { background: #E1EEF4; color: #00496B; }.datagrid table tbody td:first-child { border-left: none; }.datagrid table tbody tr:last-child td { border-bottom: none; }.datagrid table tfoot td div { border-top: 1px solid #006699;background: #E1EEF4;} .datagrid table tfoot td { padding: 0; font-size: 12px } .datagrid table tfoot td div{ padding: 2px; }.datagrid table tfoot td ul { margin: 0; padding:0; list-style: none; text-align: right; }.datagrid table tfoot li { display: inline; }.datagrid table tfoot li a { text-decoration: none; display: inline-block; padding: 2px 8px; margin: 1px;color: #FFFFFF;border: 1px solid #006699;-webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; }.datagrid table tfoot ul.active, .datagrid table tfoot ul a:hover { text-decoration: none;border-color: #006699; color: #FFFFFF; background: none; background-color:#00557F;}div.dhtmlx_window_active, div.dhx_modal_cover_dv { position: fixed !important; } table { width: 100%; table-layout: fixed; } td { border: 1px solid #35f; overflow: hidden; text-overflow: ellipsis; } td.a { width: 13%; white-space: nowrap; } td.b { width: 9%; word-wrap: break-word; } </style> <body> <h1>Autorize Report<h1> <div class="datagrid"><table> <thead><tr><th width=\"3%\">ID</th><th width=\"48%\">URL</th><th width=\"9%\">Original length</th><th width=\"9%\">Modified length</th><th width=\"9%\">Unauthorized length</th><th width=\"11%\">Authorization Enforcement Status</th><th width=\"11%\">Authorization Unauthenticated Status</th></tr></thead> <tbody>""" for i in range(0,self._log.size()): color_modified = "" if self._log.get(i)._enfocementStatus == self._enfocementStatuses[0]: color_modified = "red" if self._log.get(i)._enfocementStatus == self._enfocementStatuses[1]: color_modified = "yellow" if self._log.get(i)._enfocementStatus == self._enfocementStatuses[2]: color_modified = "LawnGreen" color_unauthorized = "" if self._log.get(i)._enfocementStatusUnauthorized == self._enfocementStatuses[0]: color_unauthorized = "red" if self._log.get(i)._enfocementStatusUnauthorized == self._enfocementStatuses[1]: color_unauthorized = "yellow" if self._log.get(i)._enfocementStatusUnauthorized == self._enfocementStatuses[2]: color_unauthorized = "LawnGreen" if enforcementStatusFilter == "All Statuses": htmlContent += "<tr><td>%d</td><td><a href=\"%s\">%s</a></td><td>%d</td><td>%d</td><td>%d</td><td bgcolor=\"%s\">%s</td><td bgcolor=\"%s\">%s</td></tr>" % (self._log.get(i)._id,self._log.get(i)._url,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, color_modified, self._log.get(i)._enfocementStatus, color_unauthorized, self._log.get(i)._enfocementStatusUnauthorized) else: if (enforcementStatusFilter == self._log.get(i)._enfocementStatus) or (enforcementStatusFilter == self._log.get(i)._enfocementStatusUnauthorized): htmlContent += "<tr><td>%d</td><td><a href=\"%s\">%s</a></td><td>%d</td><td>%d</td><td>%d</td><td bgcolor=\"%s\">%s</td><td bgcolor=\"%s\">%s</td></tr>" % (self._log.get(i)._id,self._log.get(i)._url,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, color_modified, self._log.get(i)._enfocementStatus, color_unauthorized, self._log.get(i)._enfocementStatusUnauthorized) htmlContent += "</tbody></table></div></body></html>" f = open(fileToSave.getAbsolutePath(), 'w') f.writelines(htmlContent) f.close() # # implement IContextMenuFactory # def createMenuItems(self, invocation): responses = invocation.getSelectedMessages(); if responses > 0: ret = LinkedList() requestMenuItem = JMenuItem("Send request to Autorize"); cookieMenuItem = JMenuItem("Send cookie to Autorize"); requestMenuItem.addActionListener(handleMenuItems(self,responses[0], "request")) cookieMenuItem.addActionListener(handleMenuItems(self, responses[0], "cookie")) ret.add(requestMenuItem); ret.add(cookieMenuItem); return(ret); return null; # # implement ITab # def getTabCaption(self): return "Autorize" def getUiComponent(self): return self._splitpane # # extend AbstractTableModel # def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 7 def getColumnName(self, columnIndex): if columnIndex == 0: return "ID" if columnIndex == 1: return "URL" if columnIndex == 2: return "Orig. Length" if columnIndex == 3: return "Modif. Length" if columnIndex == 4: return "Unauth. Length" if columnIndex == 5: return "Authorization Enforcement Status" if columnIndex == 6: return "Authorization Unauth. Status" return "" def getColumnClass(self, columnIndex): if columnIndex == 0: return Integer if columnIndex == 1: return String if columnIndex == 2: return Integer if columnIndex == 3: return Integer if columnIndex == 4: return Integer if columnIndex == 5: return String if columnIndex == 6: return String return String def getValueAt(self, rowIndex, columnIndex): logEntry = self._log.get(rowIndex) if columnIndex == 0: return logEntry._id if columnIndex == 1: return logEntry._url.toString() if columnIndex == 2: return len(logEntry._originalrequestResponse.getResponse()) if columnIndex == 3: return len(logEntry._requestResponse.getResponse()) if columnIndex == 4: if logEntry._unauthorizedRequestResponse != None: return len(logEntry._unauthorizedRequestResponse.getResponse()) else: #return "-" return 0 if columnIndex == 5: return logEntry._enfocementStatus if columnIndex == 6: return logEntry._enfocementStatusUnauthorized 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() # # implement IHttpListener # def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): #if (self.intercept == 1) and (toolFlag != self._callbacks.TOOL_EXTENDER): if (self.intercept == 1) and (toolFlag == self._callbacks.TOOL_PROXY): if self.prevent304.isSelected(): if messageIsRequest: requestHeaders = list(self._helpers.analyzeRequest(messageInfo).getHeaders()) newHeaders = list() found = 0 for header in requestHeaders: if not "If-None-Match:" in header and not "If-Modified-Since:" in header: newHeaders.append(header) found = 1 if found == 1: requestInfo = self._helpers.analyzeRequest(messageInfo) bodyBytes = messageInfo.getRequest()[requestInfo.getBodyOffset():] bodyStr = self._helpers.bytesToString(bodyBytes) messageInfo.setRequest(self._helpers.buildHttpMessage(newHeaders, bodyStr)) if not messageIsRequest: if not self.replaceString.getText() in self._helpers.analyzeRequest(messageInfo).getHeaders(): if self.ignore304.isSelected(): firstHeader = self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders()[0] if "304" in firstHeader or "204" in firstHeader: return if self.IFList.getModel().getSize() == 0: self.checkAuthorization(messageInfo,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected()) else: urlString = str(self._helpers.analyzeRequest(messageInfo).getUrl()) do_the_check = 1 for i in range(0,self.IFList.getModel().getSize()): if self.IFList.getModel().getElementAt(i).split(":")[0] == "Scope items only": currentURL = URL(urlString) if not self._callbacks.isInScope(currentURL): do_the_check = 0 if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Contains (simple string)": if self.IFList.getModel().getElementAt(i)[30:] not in urlString: do_the_check = 0 if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Contains (regex)": regex_string = self.IFList.getModel().getElementAt(i)[22:] p = re.compile(regex_string, re.IGNORECASE) if not p.search(urlString): do_the_check = 0 if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Not Contains (simple string)": if self.IFList.getModel().getElementAt(i)[34:] in urlString: do_the_check = 0 if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Not Contains (regex)": regex_string = self.IFList.getModel().getElementAt(i)[26:] p = re.compile(regex_string, re.IGNORECASE) if p.search(urlString): do_the_check = 0 if do_the_check: self.checkAuthorization(messageInfo,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected()) return def sendRequestToAutorizeWork(self,messageInfo): if messageInfo.getResponse() == None: message = self.makeMessage(messageInfo,False,False) requestResponse = self.makeRequest(messageInfo, message) self.checkAuthorization(requestResponse,self._helpers.analyzeResponse(requestResponse.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected()) else: self.checkAuthorization(messageInfo,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected()) def makeRequest(self, messageInfo, message): requestURL = self._helpers.analyzeRequest(messageInfo).getUrl() return self._callbacks.makeHttpRequest(self._helpers.buildHttpService(str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https"), message) def makeMessage(self, messageInfo, removeOrNot, authorizeOrNot): requestInfo = self._helpers.analyzeRequest(messageInfo) headers = requestInfo.getHeaders() if removeOrNot: headers = list(headers) removeHeaders = ArrayList() removeHeaders.add(self.replaceString.getText()[0:self.replaceString.getText().index(":")]) for header in headers[:]: for removeHeader in removeHeaders: if removeHeader in header: headers.remove(header) if authorizeOrNot: headers.append(self.replaceString.getText()) msgBody = messageInfo.getRequest()[requestInfo.getBodyOffset():] return self._helpers.buildHttpMessage(headers, msgBody) def checkBypass(self,oldStatusCode,newStatusCode,oldContentLen,newContentLen,filters,requestResponse): analyzedResponse = self._helpers.analyzeResponse(requestResponse.getResponse()) impression = "" if oldStatusCode == newStatusCode: if oldContentLen == newContentLen: impression = self._enfocementStatuses[0] else: auth_enforced = 1 for filter in filters: if str(filter).startswith("Headers (simple string): "): if not(filter[25:] in self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])): auth_enforced = 0 if str(filter).startswith("Headers (regex): "): regex_string = filter[17:] p = re.compile(regex_string, re.IGNORECASE) if not p.search(self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])): auth_enforced = 0 if str(filter).startswith("Body (simple string): "): if not(filter[22:] in self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])): auth_enforced = 0 if str(filter).startswith("Body (regex): "): regex_string = filter[14:] p = re.compile(regex_string, re.IGNORECASE) if not p.search(self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])): auth_enforced = 0 if str(filter).startswith("Full request (simple string): "): if not(filter[30:] in self._helpers.bytesToString(requestResponse.getResponse())): auth_enforced = 0 if str(filter).startswith("Full request (regex): "): regex_string = filter[22:] p = re.compile(regex_string, re.IGNORECASE) if not p.search(self._helpers.bytesToString(requestResponse.getResponse())): auth_enforced = 0 if str(filter).startswith("Content-Length: "): if newContentLen != filter: auth_enforced = 0 if auth_enforced: impression = self._enfocementStatuses[2] else: impression = self._enfocementStatuses[1] else: impression = self._enfocementStatuses[2] return impression def checkAuthorization(self, messageInfo, originalHeaders, checkUnauthorized): message = self.makeMessage(messageInfo,True,True) requestResponse = self.makeRequest(messageInfo, message) analyzedResponse = self._helpers.analyzeResponse(requestResponse.getResponse()) oldStatusCode = originalHeaders[0] newStatusCode = analyzedResponse.getHeaders()[0] oldContentLen = self.getContentLength(originalHeaders) newContentLen = self.getContentLength(analyzedResponse.getHeaders()) # Check unauthorized request if checkUnauthorized: messageUnauthorized = self.makeMessage(messageInfo,True,False) requestResponseUnauthorized = self.makeRequest(messageInfo, messageUnauthorized) analyzedResponseUnauthorized = self._helpers.analyzeResponse(requestResponseUnauthorized.getResponse()) statusCodeUnauthorized = analyzedResponseUnauthorized.getHeaders()[0] contentLenUnauthorized = self.getContentLength(analyzedResponseUnauthorized.getHeaders()) EDFilters = self.EDModel.toArray() impression = self.checkBypass(oldStatusCode,newStatusCode,oldContentLen,newContentLen,EDFilters,requestResponse) if checkUnauthorized: EDFiltersUnauth = self.EDModelUnauth.toArray() impressionUnauthorized = self.checkBypass(oldStatusCode,statusCodeUnauthorized,oldContentLen,contentLenUnauthorized,EDFiltersUnauth,requestResponseUnauthorized) self._lock.acquire() row = self._log.size() if checkUnauthorized: self._log.add(LogEntry(self.currentRequestNumber,self._callbacks.saveBuffersToTempFiles(requestResponse), self._helpers.analyzeRequest(requestResponse).getUrl(),messageInfo,impression,self._callbacks.saveBuffersToTempFiles(requestResponseUnauthorized),impressionUnauthorized)) # same requests not include again. else: self._log.add(LogEntry(self.currentRequestNumber,self._callbacks.saveBuffersToTempFiles(requestResponse), self._helpers.analyzeRequest(requestResponse).getUrl(),messageInfo,impression,None,"Disabled")) # same requests not include again. self.fireTableRowsInserted(row, row) self.currentRequestNumber = self.currentRequestNumber + 1 self._lock.release() def getContentLength(self, analyzedResponseHeaders): for header in analyzedResponseHeaders: if "Content-Length:" in header: return header; return "null" def getCookieFromMessage(self, messageInfo): headers = list(self._helpers.analyzeRequest(messageInfo.getRequest()).getHeaders()) for header in headers: if "Cookie:" in header: return header return None
class BurpExtender(IBurpExtender, ITab): def registerExtenderCallbacks(self, callbacks): print "Loading..." self._callbacks = callbacks self._callbacks.setExtensionName('Burp SPA Explorer') # self._callbacks.registerScannerCheck(self) # self._callbacks.registerExtensionStateListener(self) self._helpers = callbacks.getHelpers() self.crawlingEvent = Event() self.crawlerThread = None # main split pane self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT) self._splitpane.setBorder(EmptyBorder(20, 20, 20, 20)) # sub split pane (top) self._topPanel = JPanel(BorderLayout(10, 10)) self._topPanel.setBorder(EmptyBorder(0, 0, 10, 0)) # Setup Panel : [Target: ] [______________________] [START BUTTON] self.setupPanel = JPanel(FlowLayout(FlowLayout.LEADING, 10, 10)) self.setupPanel.add(JLabel("Target:", SwingConstants.LEFT), BorderLayout.LINE_START) self.hostField = JTextField('', 50) self.setupPanel.add(self.hostField) self.toggleButton = JButton('Start crawling', actionPerformed=self.toggleCrawl) self.setupPanel.add(self.toggleButton) self._topPanel.add(self.setupPanel, BorderLayout.PAGE_START) # Options Panel : [Buttons] [ RegEx ] self.optionsPanel = JPanel() self.optionsPanel.setLayout( BoxLayout(self.optionsPanel, BoxLayout.LINE_AXIS)) # Button options panel : [Add][Edit][Up][Down][Remove] self.buttonOptionsPanel = JPanel() self.buttonOptionsPanel.setLayout( BoxLayout(self.buttonOptionsPanel, BoxLayout.PAGE_AXIS)) self.addRegexButton = JButton('Add', actionPerformed=self.addRegex) self.buttonOptionsPanel.add(self.addRegexButton) self.editRegexButton = JButton('Edit', actionPerformed=self.editRegex) self.buttonOptionsPanel.add(self.editRegexButton) self.moveRegexUpButton = JButton('Move up', actionPerformed=self.moveRegexUp) self.buttonOptionsPanel.add(self.moveRegexUpButton) self.moveRegexDownButton = JButton('Move down', actionPerformed=self.moveRegexDown) self.buttonOptionsPanel.add(self.moveRegexDownButton) self.removeRegexButton = JButton('Remove', actionPerformed=self.removeRegex) self.buttonOptionsPanel.add(self.removeRegexButton) self.buttonOptionsPanel.add(Box.createVerticalGlue()) self.optionsPanel.add(self.buttonOptionsPanel) self.optionsPanel.add(Box.createHorizontalStrut(20)) self.regexTableModel = RegexTableModel([x for x in regex]) self.regexTable = Table(self.regexTableModel) self.regexScrollPane = JScrollPane(self.regexTable) self.optionsPanel.add(self.regexScrollPane) self._topPanel.add(self.optionsPanel, BorderLayout.CENTER) self._splitpane.setTopComponent(self._topPanel) # Bottom Panel self._bottomPanel = JPanel(BorderLayout(10, 10)) #self._bottomPanel.setLayout(BoxLayout(self._bottomPanel,BoxLayout.PAGE_AXIS)) # Status bar self.crawlStatusPanel = JPanel(FlowLayout(FlowLayout.LEADING, 10, 10)) self.crawlStatusPanel.add(JLabel("Status: ", SwingConstants.LEFT)) self.crawlStatusLabel = JLabel("Ready to crawl", SwingConstants.LEFT) self.crawlStatusPanel.add(self.crawlStatusLabel) # Result Table self.resultTableModel = Result([]) self.resultTable = Table(self.resultTableModel) self.resultTable.setAutoCreateRowSorter(True) self.resultScrollPane = JScrollPane(self.resultTable) # Result Table popup menu def selectWhenRightClickEvent(event): def select(e): rowAtPoint = self.resultTable.rowAtPoint( SwingUtilities.convertPoint(self.resultTablePopupMenu, Point(0, 0), self.resultTable)) if rowAtPoint > -1: self.resultTable.setRowSelectionInterval( rowAtPoint, rowAtPoint) SwingUtilities.invokeLater(CrawlerRunnable(select, (event, ))) self.resultTablePopupMenu = JPopupMenu( popupMenuWillBecomeVisible=selectWhenRightClickEvent) self.resultTablePopupMenu.add( JMenuItem("Send to scanner", actionPerformed=self.sendToScanner)) self.resultTablePopupMenu.add( JMenuItem("Send to repeater", actionPerformed=self.sendToRepeater)) self.resultTablePopupMenu.add( JMenuItem("Send to intruder", actionPerformed=self.sendToIntruder)) self.resultTablePopupMenu.add( JMenuItem("Send to spider", actionPerformed=self.sendToSpider)) self.resultTable.setComponentPopupMenu(self.resultTablePopupMenu) self._bottomPanel.add(self.resultScrollPane, BorderLayout.CENTER) self._bottomPanel.add(self.crawlStatusPanel, BorderLayout.SOUTH) self._splitpane.setBottomComponent(self._bottomPanel) self._splitpane.setDividerLocation(300 + self._splitpane.getInsets().left) callbacks.customizeUiComponent(self._splitpane) callbacks.addSuiteTab(self) explorerMenu = ExplorerMenu(self) callbacks.registerContextMenuFactory(explorerMenu) print "SPA Explorer custom menu loaded" #print "Loading chrome driver" #a = Test(os.path.dirname(os.path.realpath('selenium-client.jar')) + '/chromedriver.exe') #print "Chrome driver started" print "Burp SPA Explorer loaded" # Button Actions def getURLComponents(self, url): return (url.getHost(), (443 if url.getProtocol() == 'https' else 80) if url.getPort() == -1 else url.getPort(), url.getProtocol() == 'https') def sendToScanner(self, event): url = URL( self.resultTable.getValueAt(self.resultTable.getSelectedRow(), 1)) urlComp = self.getURLComponents(url) self._callbacks.doActiveScan(urlComp[0], urlComp[1], urlComp[2], self._helpers.buildHttpRequest(url)) def sendToRepeater(self, event): url = URL( self.resultTable.getValueAt(self.resultTable.getSelectedRow(), 1)) urlComp = self.getURLComponents(url) self._callbacks.sendToRepeater(urlComp[0], urlComp[1], urlComp[2], self._helpers.buildHttpRequest(url), None) def sendToIntruder(self, event): url = URL( self.resultTable.getValueAt(self.resultTable.getSelectedRow(), 1)) urlComp = self.getURLComponents(url) self._callbacks.sendToIntruder(urlComp[0], urlComp[1], urlComp[2], self._helpers.buildHttpRequest(url)) def sendToSpider(self, event): url = URL( self.resultTable.getValueAt(self.resultTable.getSelectedRow(), 1)) self._callbacks.sendToSpider(url) def addRegex(self, event): optionPane = JOptionPane() dialog = optionPane.createDialog(self._splitpane, "Add RegEx") panel = JPanel(GridLayout(0, 2)) panel.setBorder(EmptyBorder(10, 10, 10, 10)) nameField = JTextField('', 15) panel.add(JLabel("Name:", SwingConstants.LEFT)) panel.add(nameField) regexField = JTextField('', 15) panel.add(JLabel("RegEx:", SwingConstants.LEFT)) panel.add(regexField) crawlField = JCheckBox() panel.add(JLabel("Crawl:", SwingConstants.LEFT)) panel.add(crawlField) def closeDialog(event): if len(nameField.text) == 0 or len(regexField.text) == 0: JOptionPane.showMessageDialog(self._splitpane, "Name or RegEx can't be empty", "Error", JOptionPane.ERROR_MESSAGE) return self.regexTableModel.addRow( [nameField.text, regexField.text, crawlField.isSelected()]) dialog.hide() addButton = JButton('OK', actionPerformed=closeDialog) panel.add(addButton) dialog.setSize(600, 200) dialog.setContentPane(panel) self._callbacks.customizeUiComponent(dialog) dialog.show() return True def editRegex(self, event): selectedRowIdx = self.regexTable.getSelectedRow() if selectedRowIdx == -1: return False selectedRow = self.regexTableModel.data[selectedRowIdx] optionPane = JOptionPane() dialog = optionPane.createDialog(self._splitpane, "Edit RegEx") panel = JPanel(GridLayout(0, 2)) panel.setBorder(EmptyBorder(10, 10, 10, 10)) nameField = JTextField('', 15) nameField.text = selectedRow[0] panel.add(JLabel("Name:", SwingConstants.LEFT)) panel.add(nameField) regexField = JTextField('', 15) regexField.text = selectedRow[1] panel.add(JLabel("RegEx:", SwingConstants.LEFT)) panel.add(regexField) crawlField = JCheckBox() crawlField.setSelected(selectedRow[2]) panel.add(JLabel("Crawl:", SwingConstants.LEFT)) panel.add(crawlField) def closeDialog(event): if len(nameField.text) == 0 or len(regexField.text) == 0: JOptionPane.showMessageDialog(self._splitpane, "Name or RegEx can't be empty", "Error", JOptionPane.ERROR_MESSAGE) return self.regexTableModel.editRow( selectedRowIdx, [nameField.text, regexField.text, crawlField.isSelected()]) dialog.hide() editButton = JButton('OK', actionPerformed=closeDialog) panel.add(editButton) dialog.setSize(600, 200) dialog.setContentPane(panel) self._callbacks.customizeUiComponent(dialog) dialog.show() return True def moveRegexDown(self, event): idxs = self.regexTable.getSelectedRows() if self.regexTableModel.getRowCount() - 1 in idxs: return False self.regexTable.clearSelection() for i in sorted(idxs)[::-1]: self.regexTableModel.moveDown(i) self.regexTable.addRowSelectionInterval(i + 1, i + 1) return True def moveRegexUp(self, event): idxs = self.regexTable.getSelectedRows() if 0 in idxs: return False self.regexTable.clearSelection() for i in sorted(idxs): self.regexTableModel.moveUp(i) self.regexTable.addRowSelectionInterval(i - 1, i - 1) return True def removeRegex(self, event): idx = self.regexTable.getSelectedRows() for i in sorted(idx)[::-1]: self.regexTableModel.removeRow(i) return True # Implement ITab def getTabCaption(self): return "SPA Explorer" def getUiComponent(self): return self._splitpane def crawl(self, event): print("Starting") host = self.hostField.text if host.find("://") == -1: host = "http://" + host try: self._callbacks.includeInScope(URL(host)) except: JOptionPane.showMessageDialog(self._splitpane, "Can't add host to scope", "Error", JOptionPane.ERROR_MESSAGE) return self.resultTableModel.clearAllRow() self.crawlingEvent.set() self.crawlerThread = Thread(target=self.crawl_thread, args=(host, )) self.crawlerThread.start() print("Started") def stopCrawling(self, event): print("Clear event") self.crawlingEvent.clear() # Disable button if self.toggleButton.text == "Stop crawling": # If button is still "Stop crawling" (Thread still running), disable button self.toggleButton.setEnabled(False) def toggleCrawl(self, event): if (self.crawlerThread == None or not self.crawlerThread.is_alive()): self.crawl(event) #self.toggleButton.setText("Start crawling") else: self.stopCrawling(event) #self.toggleButton.setText("Stop crawling") def crawl_thread(self, host): # print(self, host) print("Crawl thread started") SwingUtilities.invokeLater( CrawlerRunnable(self.toggleButton.setText, ("Stop crawling", ))) SwingUtilities.invokeLater( CrawlerRunnable(self.addRegexButton.setEnabled, (False, ))) SwingUtilities.invokeLater( CrawlerRunnable(self.editRegexButton.setEnabled, (False, ))) SwingUtilities.invokeLater( CrawlerRunnable(self.moveRegexUpButton.setEnabled, (False, ))) SwingUtilities.invokeLater( CrawlerRunnable(self.moveRegexDownButton.setEnabled, (False, ))) SwingUtilities.invokeLater( CrawlerRunnable(self.removeRegexButton.setEnabled, (False, ))) pageType = {} # url -> type pageContentHash = {} # hash -> url list def concatURL(baseURL, link): return URL(URL(baseURL), link).toString() def makeRequest(url): url = URL(url) if not self._callbacks.isInScope(url): #self.logger.addRow(url.toString()+" is out of scope") raise ValueError("URL is out of scope") prot = url.getProtocol() host = url.getHost() port = url.getPort() if port == -1: port = 80 if prot == "http" else 443 httpService = self._helpers.buildHttpService(host, port, prot) reqRes = self._callbacks.makeHttpRequest( httpService, self._helpers.buildHttpRequest(url)) self._callbacks.addToSiteMap(reqRes) resp = reqRes.getResponse() respInfo = self._helpers.analyzeResponse(resp) respBody = self._helpers.bytesToString( resp[respInfo.getBodyOffset():]) return respBody def matchRegex(baseURL, res): toRet = [] for (name, regStr, ret) in self.regexTableModel.data: matchObj = re.findall(regStr, res, re.M | re.I) for i in matchObj: try: if i.find('http://') == 0 or i.find('https://') == 0: url = i elif i[0] == '/': url = host + i else: url = host + '/' + i if url not in pageType: pageType[url] = name SwingUtilities.invokeLater( CrawlerRunnable(self.resultTableModel.addRow, ([name, url], ))) if ret: toRet.append(url) except: print("Error when trying to save result ", i, sys.exc_info()[0], sys.exc_info()[1]) return toRet def getAllLink(url): toRet = [] try: print("Making request", url) r = makeRequest(url) print("Done request", len(r)) hash = hashlib.sha256(r.encode('utf-8')).hexdigest() #print(r.text) if hash in pageContentHash: print("Content hash is the same as ", pageContentHash[hash][0]) pageContentHash[hash].append(url) return toRet else: pageContentHash[hash] = [url] toRet += matchRegex(url, r) except BaseException as e: print("Error while making request to ", url, e) except: print("Error while making request to ", url, sys.exc_info()[0], sys.exc_info()[1]) return toRet crawledPage = [host] crawledNow = 0 SwingUtilities.invokeLater( CrawlerRunnable(self.resultTableModel.addRow, (["TARGET", host], ))) while crawledNow < len(crawledPage): if self.crawlingEvent.is_set(): print("Crawling", crawledPage[crawledNow]) SwingUtilities.invokeLater( CrawlerRunnable(self.crawlStatusLabel.setText, ("Crawling " + crawledPage[crawledNow], ))) for i in getAllLink(crawledPage[crawledNow]): if i not in crawledPage: print("ADD:", i) crawledPage.append(i) crawledNow += 1 else: print("Stop Requested") break print(crawledNow, crawledPage) output = [] SwingUtilities.invokeLater( CrawlerRunnable(self.toggleButton.setText, ("Start crawling", ))) SwingUtilities.invokeLater( CrawlerRunnable(self.toggleButton.setEnabled, (True, ))) SwingUtilities.invokeLater( CrawlerRunnable(self.addRegexButton.setEnabled, (True, ))) SwingUtilities.invokeLater( CrawlerRunnable(self.editRegexButton.setEnabled, (True, ))) SwingUtilities.invokeLater( CrawlerRunnable(self.moveRegexUpButton.setEnabled, (True, ))) SwingUtilities.invokeLater( CrawlerRunnable(self.moveRegexDownButton.setEnabled, (True, ))) SwingUtilities.invokeLater( CrawlerRunnable(self.removeRegexButton.setEnabled, (True, ))) SwingUtilities.invokeLater( CrawlerRunnable(self.crawlStatusLabel.setText, ("Ready to crawl", ))) self.crawlingEvent.clear() print("Completed")
def registerExtenderCallbacks(self, callbacks): print "Loading..." self._callbacks = callbacks self._callbacks.setExtensionName('Burp SPA Explorer') # self._callbacks.registerScannerCheck(self) # self._callbacks.registerExtensionStateListener(self) self._helpers = callbacks.getHelpers() self.crawlingEvent = Event() self.crawlerThread = None # main split pane self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT) self._splitpane.setBorder(EmptyBorder(20, 20, 20, 20)) # sub split pane (top) self._topPanel = JPanel(BorderLayout(10, 10)) self._topPanel.setBorder(EmptyBorder(0, 0, 10, 0)) # Setup Panel : [Target: ] [______________________] [START BUTTON] self.setupPanel = JPanel(FlowLayout(FlowLayout.LEADING, 10, 10)) self.setupPanel.add(JLabel("Target:", SwingConstants.LEFT), BorderLayout.LINE_START) self.hostField = JTextField('', 50) self.setupPanel.add(self.hostField) self.toggleButton = JButton('Start crawling', actionPerformed=self.toggleCrawl) self.setupPanel.add(self.toggleButton) self._topPanel.add(self.setupPanel, BorderLayout.PAGE_START) # Options Panel : [Buttons] [ RegEx ] self.optionsPanel = JPanel() self.optionsPanel.setLayout( BoxLayout(self.optionsPanel, BoxLayout.LINE_AXIS)) # Button options panel : [Add][Edit][Up][Down][Remove] self.buttonOptionsPanel = JPanel() self.buttonOptionsPanel.setLayout( BoxLayout(self.buttonOptionsPanel, BoxLayout.PAGE_AXIS)) self.addRegexButton = JButton('Add', actionPerformed=self.addRegex) self.buttonOptionsPanel.add(self.addRegexButton) self.editRegexButton = JButton('Edit', actionPerformed=self.editRegex) self.buttonOptionsPanel.add(self.editRegexButton) self.moveRegexUpButton = JButton('Move up', actionPerformed=self.moveRegexUp) self.buttonOptionsPanel.add(self.moveRegexUpButton) self.moveRegexDownButton = JButton('Move down', actionPerformed=self.moveRegexDown) self.buttonOptionsPanel.add(self.moveRegexDownButton) self.removeRegexButton = JButton('Remove', actionPerformed=self.removeRegex) self.buttonOptionsPanel.add(self.removeRegexButton) self.buttonOptionsPanel.add(Box.createVerticalGlue()) self.optionsPanel.add(self.buttonOptionsPanel) self.optionsPanel.add(Box.createHorizontalStrut(20)) self.regexTableModel = RegexTableModel([x for x in regex]) self.regexTable = Table(self.regexTableModel) self.regexScrollPane = JScrollPane(self.regexTable) self.optionsPanel.add(self.regexScrollPane) self._topPanel.add(self.optionsPanel, BorderLayout.CENTER) self._splitpane.setTopComponent(self._topPanel) # Bottom Panel self._bottomPanel = JPanel(BorderLayout(10, 10)) #self._bottomPanel.setLayout(BoxLayout(self._bottomPanel,BoxLayout.PAGE_AXIS)) # Status bar self.crawlStatusPanel = JPanel(FlowLayout(FlowLayout.LEADING, 10, 10)) self.crawlStatusPanel.add(JLabel("Status: ", SwingConstants.LEFT)) self.crawlStatusLabel = JLabel("Ready to crawl", SwingConstants.LEFT) self.crawlStatusPanel.add(self.crawlStatusLabel) # Result Table self.resultTableModel = Result([]) self.resultTable = Table(self.resultTableModel) self.resultTable.setAutoCreateRowSorter(True) self.resultScrollPane = JScrollPane(self.resultTable) # Result Table popup menu def selectWhenRightClickEvent(event): def select(e): rowAtPoint = self.resultTable.rowAtPoint( SwingUtilities.convertPoint(self.resultTablePopupMenu, Point(0, 0), self.resultTable)) if rowAtPoint > -1: self.resultTable.setRowSelectionInterval( rowAtPoint, rowAtPoint) SwingUtilities.invokeLater(CrawlerRunnable(select, (event, ))) self.resultTablePopupMenu = JPopupMenu( popupMenuWillBecomeVisible=selectWhenRightClickEvent) self.resultTablePopupMenu.add( JMenuItem("Send to scanner", actionPerformed=self.sendToScanner)) self.resultTablePopupMenu.add( JMenuItem("Send to repeater", actionPerformed=self.sendToRepeater)) self.resultTablePopupMenu.add( JMenuItem("Send to intruder", actionPerformed=self.sendToIntruder)) self.resultTablePopupMenu.add( JMenuItem("Send to spider", actionPerformed=self.sendToSpider)) self.resultTable.setComponentPopupMenu(self.resultTablePopupMenu) self._bottomPanel.add(self.resultScrollPane, BorderLayout.CENTER) self._bottomPanel.add(self.crawlStatusPanel, BorderLayout.SOUTH) self._splitpane.setBottomComponent(self._bottomPanel) self._splitpane.setDividerLocation(300 + self._splitpane.getInsets().left) callbacks.customizeUiComponent(self._splitpane) callbacks.addSuiteTab(self) explorerMenu = ExplorerMenu(self) callbacks.registerContextMenuFactory(explorerMenu) print "SPA Explorer custom menu loaded" #print "Loading chrome driver" #a = Test(os.path.dirname(os.path.realpath('selenium-client.jar')) + '/chromedriver.exe') #print "Chrome driver started" print "Burp SPA Explorer loaded"
def __init__(self, name, iconName, tooltip, shortcut, height, app): ToggleDialog.__init__(self, name, iconName, tooltip, shortcut, height) self.app = app tools = app.tools #Main panel of the dialog mainPnl = JPanel(BorderLayout()) mainPnl.setBorder(BorderFactory.createEmptyBorder(0, 1, 1, 1)) ### First tab: errors selection and download ########################### #ComboBox with tools names self.toolsComboModel = DefaultComboBoxModel() for tool in tools: self.add_data_to_models(tool) self.toolsCombo = JComboBox(self.toolsComboModel, actionListener=ToolsComboListener(app)) renderer = ToolsComboRenderer(self.app) renderer.setPreferredSize(Dimension(20, 20)) self.toolsCombo.setRenderer(renderer) self.toolsCombo.setToolTipText(app.strings.getString("Select_a_quality_assurance_tool")) #ComboBox with categories names ("views"), of the selected tool self.viewsCombo = JComboBox(actionListener=ViewsComboListener(app)) self.viewsCombo.setToolTipText(app.strings.getString("Select_a_category_of_error")) #Popup for checks table self.checkPopup = JPopupMenu() #add favourite check self.menuItemAdd = JMenuItem(self.app.strings.getString("Add_to_favourites")) self.menuItemAdd.setIcon(ImageIcon(File.separator.join([self.app.SCRIPTDIR, "tools", "data", "Favourites", "icons", "tool_16.png"]))) self.menuItemAdd.addActionListener(PopupActionListener(self.app)) self.checkPopup.add(self.menuItemAdd) #remove favourite check self.menuItemRemove = JMenuItem(self.app.strings.getString("Remove_from_favourites")) self.menuItemRemove.setIcon(ImageIcon(File.separator.join([self.app.SCRIPTDIR, "tools", "data", "Favourites", "icons", "black_tool_16.png"]))) self.menuItemRemove.addActionListener(PopupActionListener(self.app)) self.checkPopup.add(self.menuItemRemove) #Help link for selected check self.menuItemHelp = JMenuItem(self.app.strings.getString("check_help")) self.menuItemHelp.setIcon(ImageIcon(File.separator.join([self.app.SCRIPTDIR, "images", "icons", "info_16.png"]))) self.checkPopup.add(self.menuItemHelp) self.menuItemHelp.addActionListener(PopupActionListener(self.app)) #Table with checks of selected tool and view self.checksTable = JTable() self.iconrenderer = IconRenderer() self.iconrenderer.setHorizontalAlignment(JLabel.CENTER) scrollPane = JScrollPane(self.checksTable) self.checksTable.setFillsViewportHeight(True) tableSelectionModel = self.checksTable.getSelectionModel() tableSelectionModel.addListSelectionListener(ChecksTableListener(app)) self.checksTable.addMouseListener(ChecksTableClickListener(app, self.checkPopup, self.checksTable)) #Favourite area status indicator self.favAreaIndicator = JLabel() self.update_favourite_zone_indicator() self.favAreaIndicator.addMouseListener(FavAreaIndicatorListener(app)) #label with OSM id of the object currently edited and number of #errors still to review self.checksTextFld = JTextField("", editable=0, border=None, background=None) #checks buttons btnsIconsDir = File.separator.join([app.SCRIPTDIR, "images", "icons"]) downloadIcon = ImageIcon(File.separator.join([btnsIconsDir, "download.png"])) self.downloadBtn = JButton(downloadIcon, actionPerformed=app.on_downloadBtn_clicked, enabled=0) startIcon = ImageIcon(File.separator.join([btnsIconsDir, "start_fixing.png"])) self.startBtn = JButton(startIcon, actionPerformed=app.on_startBtn_clicked, enabled=0) self.downloadBtn.setToolTipText(app.strings.getString("Download_errors_in_this_area")) self.startBtn.setToolTipText(app.strings.getString("Start_fixing_the_selected_errors")) #tab layout panel1 = JPanel(BorderLayout(0, 1)) comboboxesPnl = JPanel(GridLayout(0, 2, 5, 0)) comboboxesPnl.add(self.toolsCombo) comboboxesPnl.add(self.viewsCombo) checksPnl = JPanel(BorderLayout(0, 1)) checksPnl.add(scrollPane, BorderLayout.CENTER) self.statsPanel = JPanel(BorderLayout(4, 0)) self.statsPanel_def_color = self.statsPanel.getBackground() self.statsPanel.add(self.checksTextFld, BorderLayout.CENTER) self.statsPanel.add(self.favAreaIndicator, BorderLayout.LINE_START) checksPnl.add(self.statsPanel, BorderLayout.PAGE_END) checksButtonsPnl = JPanel(GridLayout(0, 2, 0, 0)) checksButtonsPnl.add(self.downloadBtn) checksButtonsPnl.add(self.startBtn) panel1.add(comboboxesPnl, BorderLayout.PAGE_START) panel1.add(checksPnl, BorderLayout.CENTER) panel1.add(checksButtonsPnl, BorderLayout.PAGE_END) ### Second tab: errors fixing ########################################## #label with error stats self.errorTextFld = JTextField("", editable=0, border=None, background=None) #label with current error description self.errorDesc = JLabel("") self.errorDesc.setAlignmentX(0.5) #error buttons errorInfoBtnIcon = ImageProvider.get("info") self.errorInfoBtn = JButton(errorInfoBtnIcon, actionPerformed=app.on_errorInfoBtn_clicked, enabled=0) notErrorIcon = ImageIcon(File.separator.join([btnsIconsDir, "not_error.png"])) self.notErrorBtn = JButton(notErrorIcon, actionPerformed=app.on_falsePositiveBtn_clicked, enabled=0) ignoreIcon = ImageIcon(File.separator.join([btnsIconsDir, "skip.png"])) self.ignoreBtn = JButton(ignoreIcon, actionPerformed=app.on_ignoreBtn_clicked, enabled=0) correctedIcon = ImageIcon(File.separator.join([btnsIconsDir, "corrected.png"])) self.correctedBtn = JButton(correctedIcon, actionPerformed=app.on_correctedBtn_clicked, enabled=0) nextIcon = ImageIcon(File.separator.join([btnsIconsDir, "next.png"])) self.nextBtn = JButton(nextIcon, actionPerformed=app.on_nextBtn_clicked, enabled=0) #self.nextBtn.setMnemonic(KeyEvent.VK_RIGHT) self.errorInfoBtn.setToolTipText(app.strings.getString("open_error_info_dialog")) self.notErrorBtn.setToolTipText(app.strings.getString("flag_false_positive")) self.ignoreBtn.setToolTipText(app.strings.getString("Skip_and_don't_show_me_this_error_again")) self.correctedBtn.setToolTipText(app.strings.getString("flag_corrected_error")) self.nextBtn.setToolTipText(app.strings.getString("Go_to_next_error")) #tab layout self.panel2 = JPanel(BorderLayout()) self.panel2.add(self.errorTextFld, BorderLayout.PAGE_START) self.panel2.add(self.errorDesc, BorderLayout.CENTER) errorButtonsPanel = JPanel(GridLayout(0, 5, 0, 0)) errorButtonsPanel.add(self.errorInfoBtn) errorButtonsPanel.add(self.notErrorBtn) errorButtonsPanel.add(self.ignoreBtn) errorButtonsPanel.add(self.correctedBtn) errorButtonsPanel.add(self.nextBtn) self.panel2.add(errorButtonsPanel, BorderLayout.PAGE_END) #Layout self.tabbedPane = JTabbedPane() self.tabbedPane.addTab(self.app.strings.getString("Download"), None, panel1, self.app.strings.getString("download_tab")) mainPnl.add(self.tabbedPane, BorderLayout.CENTER) self.createLayout(mainPnl, False, None)
class QatDialog(ToggleDialog): """ToggleDialog for error type selection and buttons for reviewing errors in sequence """ def __init__(self, name, iconName, tooltip, shortcut, height, app): ToggleDialog.__init__(self, name, iconName, tooltip, shortcut, height) self.app = app tools = app.tools #Main panel of the dialog mainPnl = JPanel(BorderLayout()) mainPnl.setBorder(BorderFactory.createEmptyBorder(0, 1, 1, 1)) ### First tab: errors selection and download ########################### #ComboBox with tools names self.toolsComboModel = DefaultComboBoxModel() for tool in tools: self.add_data_to_models(tool) self.toolsCombo = JComboBox(self.toolsComboModel, actionListener=ToolsComboListener(app)) renderer = ToolsComboRenderer(self.app) renderer.setPreferredSize(Dimension(20, 20)) self.toolsCombo.setRenderer(renderer) self.toolsCombo.setToolTipText(app.strings.getString("Select_a_quality_assurance_tool")) #ComboBox with categories names ("views"), of the selected tool self.viewsCombo = JComboBox(actionListener=ViewsComboListener(app)) self.viewsCombo.setToolTipText(app.strings.getString("Select_a_category_of_error")) #Popup for checks table self.checkPopup = JPopupMenu() #add favourite check self.menuItemAdd = JMenuItem(self.app.strings.getString("Add_to_favourites")) self.menuItemAdd.setIcon(ImageIcon(File.separator.join([self.app.SCRIPTDIR, "tools", "data", "Favourites", "icons", "tool_16.png"]))) self.menuItemAdd.addActionListener(PopupActionListener(self.app)) self.checkPopup.add(self.menuItemAdd) #remove favourite check self.menuItemRemove = JMenuItem(self.app.strings.getString("Remove_from_favourites")) self.menuItemRemove.setIcon(ImageIcon(File.separator.join([self.app.SCRIPTDIR, "tools", "data", "Favourites", "icons", "black_tool_16.png"]))) self.menuItemRemove.addActionListener(PopupActionListener(self.app)) self.checkPopup.add(self.menuItemRemove) #Help link for selected check self.menuItemHelp = JMenuItem(self.app.strings.getString("check_help")) self.menuItemHelp.setIcon(ImageIcon(File.separator.join([self.app.SCRIPTDIR, "images", "icons", "info_16.png"]))) self.checkPopup.add(self.menuItemHelp) self.menuItemHelp.addActionListener(PopupActionListener(self.app)) #Table with checks of selected tool and view self.checksTable = JTable() self.iconrenderer = IconRenderer() self.iconrenderer.setHorizontalAlignment(JLabel.CENTER) scrollPane = JScrollPane(self.checksTable) self.checksTable.setFillsViewportHeight(True) tableSelectionModel = self.checksTable.getSelectionModel() tableSelectionModel.addListSelectionListener(ChecksTableListener(app)) self.checksTable.addMouseListener(ChecksTableClickListener(app, self.checkPopup, self.checksTable)) #Favourite area status indicator self.favAreaIndicator = JLabel() self.update_favourite_zone_indicator() self.favAreaIndicator.addMouseListener(FavAreaIndicatorListener(app)) #label with OSM id of the object currently edited and number of #errors still to review self.checksTextFld = JTextField("", editable=0, border=None, background=None) #checks buttons btnsIconsDir = File.separator.join([app.SCRIPTDIR, "images", "icons"]) downloadIcon = ImageIcon(File.separator.join([btnsIconsDir, "download.png"])) self.downloadBtn = JButton(downloadIcon, actionPerformed=app.on_downloadBtn_clicked, enabled=0) startIcon = ImageIcon(File.separator.join([btnsIconsDir, "start_fixing.png"])) self.startBtn = JButton(startIcon, actionPerformed=app.on_startBtn_clicked, enabled=0) self.downloadBtn.setToolTipText(app.strings.getString("Download_errors_in_this_area")) self.startBtn.setToolTipText(app.strings.getString("Start_fixing_the_selected_errors")) #tab layout panel1 = JPanel(BorderLayout(0, 1)) comboboxesPnl = JPanel(GridLayout(0, 2, 5, 0)) comboboxesPnl.add(self.toolsCombo) comboboxesPnl.add(self.viewsCombo) checksPnl = JPanel(BorderLayout(0, 1)) checksPnl.add(scrollPane, BorderLayout.CENTER) self.statsPanel = JPanel(BorderLayout(4, 0)) self.statsPanel_def_color = self.statsPanel.getBackground() self.statsPanel.add(self.checksTextFld, BorderLayout.CENTER) self.statsPanel.add(self.favAreaIndicator, BorderLayout.LINE_START) checksPnl.add(self.statsPanel, BorderLayout.PAGE_END) checksButtonsPnl = JPanel(GridLayout(0, 2, 0, 0)) checksButtonsPnl.add(self.downloadBtn) checksButtonsPnl.add(self.startBtn) panel1.add(comboboxesPnl, BorderLayout.PAGE_START) panel1.add(checksPnl, BorderLayout.CENTER) panel1.add(checksButtonsPnl, BorderLayout.PAGE_END) ### Second tab: errors fixing ########################################## #label with error stats self.errorTextFld = JTextField("", editable=0, border=None, background=None) #label with current error description self.errorDesc = JLabel("") self.errorDesc.setAlignmentX(0.5) #error buttons errorInfoBtnIcon = ImageProvider.get("info") self.errorInfoBtn = JButton(errorInfoBtnIcon, actionPerformed=app.on_errorInfoBtn_clicked, enabled=0) notErrorIcon = ImageIcon(File.separator.join([btnsIconsDir, "not_error.png"])) self.notErrorBtn = JButton(notErrorIcon, actionPerformed=app.on_falsePositiveBtn_clicked, enabled=0) ignoreIcon = ImageIcon(File.separator.join([btnsIconsDir, "skip.png"])) self.ignoreBtn = JButton(ignoreIcon, actionPerformed=app.on_ignoreBtn_clicked, enabled=0) correctedIcon = ImageIcon(File.separator.join([btnsIconsDir, "corrected.png"])) self.correctedBtn = JButton(correctedIcon, actionPerformed=app.on_correctedBtn_clicked, enabled=0) nextIcon = ImageIcon(File.separator.join([btnsIconsDir, "next.png"])) self.nextBtn = JButton(nextIcon, actionPerformed=app.on_nextBtn_clicked, enabled=0) #self.nextBtn.setMnemonic(KeyEvent.VK_RIGHT) self.errorInfoBtn.setToolTipText(app.strings.getString("open_error_info_dialog")) self.notErrorBtn.setToolTipText(app.strings.getString("flag_false_positive")) self.ignoreBtn.setToolTipText(app.strings.getString("Skip_and_don't_show_me_this_error_again")) self.correctedBtn.setToolTipText(app.strings.getString("flag_corrected_error")) self.nextBtn.setToolTipText(app.strings.getString("Go_to_next_error")) #tab layout self.panel2 = JPanel(BorderLayout()) self.panel2.add(self.errorTextFld, BorderLayout.PAGE_START) self.panel2.add(self.errorDesc, BorderLayout.CENTER) errorButtonsPanel = JPanel(GridLayout(0, 5, 0, 0)) errorButtonsPanel.add(self.errorInfoBtn) errorButtonsPanel.add(self.notErrorBtn) errorButtonsPanel.add(self.ignoreBtn) errorButtonsPanel.add(self.correctedBtn) errorButtonsPanel.add(self.nextBtn) self.panel2.add(errorButtonsPanel, BorderLayout.PAGE_END) #Layout self.tabbedPane = JTabbedPane() self.tabbedPane.addTab(self.app.strings.getString("Download"), None, panel1, self.app.strings.getString("download_tab")) mainPnl.add(self.tabbedPane, BorderLayout.CENTER) self.createLayout(mainPnl, False, None) def add_data_to_models(self, tool): """Add data of a tool to the models of the dialog components """ #tools combobox model if tool == self.app.favouritesTool: self.toolsComboModel.addElement(JSeparator()) self.toolsComboModel.addElement(tool) #views combobox model tool.viewsComboModel = DefaultComboBoxModel() for view in tool.views: tool.viewsComboModel.addElement(view.title) #checks table, one TableModel for each view, of each tool columns = ["", self.app.strings.getString("Check"), self.app.strings.getString("Errors")] for view in tool.views: tableRows = [] for check in view.checks: if check.icon is not None: icon = check.icon else: icon = "" errorsNumber = "" tableRows.append([icon, check.title, errorsNumber]) view.tableModel = MyTableModel(tableRows, columns) def update_favourite_zone_indicator(self): #icon if self.app.favZone is not None: self.favAreaIndicator.setIcon(self.app.favZone.icon) #tooltip messageArguments = array([self.app.favZone.name], String) formatter = MessageFormat("") formatter.applyPattern(self.app.strings.getString("favAreaIndicator_tooltip")) msg = formatter.format(messageArguments) self.favAreaIndicator.setToolTipText(msg) #status self.favAreaIndicator.setVisible(self.app.favouriteZoneStatus) def set_checksTextFld_color(self, color): """Change color of textField under checksTable """ colors = {"white": (255, 255, 255), "black": (0, 0, 0), "green": (100, 200, 0), "red": (200, 0, 0)} if color == "default": self.statsPanel.background = self.statsPanel_def_color self.checksTextFld.foreground = colors["black"] else: self.statsPanel.background = colors[color] self.checksTextFld.foreground = colors["white"] def change_selection(self, source): """Change comboboxes and checks table selections after a selection has been made by the user """ if source in ("menu", "layer", "add favourite"): self.app.selectionChangedFromMenuOrLayer = True self.toolsCombo.setSelectedItem(self.app.selectedTool) self.viewsCombo.setModel(self.app.selectedTool.viewsComboModel) self.viewsCombo.setSelectedItem(self.app.selectedView.title) self.checksTable.setModel(self.app.selectedTableModel) self.refresh_checksTable_columns_geometries() for i, c in enumerate(self.app.selectedView.checks): if c == self.app.selectedChecks[0]: break self.checksTable.setRowSelectionInterval(i, i) self.app.selectionChangedFromMenuOrLayer = False else: self.app.selectionChangedFromMenuOrLayer = False if source == "toolsCombo": self.viewsCombo.setModel(self.app.selectedTool.viewsComboModel) self.viewsCombo.setSelectedIndex(0) elif source == "viewsCombo": self.checksTable.setModel(self.app.selectedTableModel) self.refresh_checksTable_columns_geometries() if self.app.selectedView.checks != []: # favourite checks may be none self.checksTable.setRowSelectionInterval(0, 0) def refresh_checksTable_columns_geometries(self): self.checksTable.getColumnModel().getColumn(0).setCellRenderer(self.iconrenderer) self.checksTable.getColumnModel().getColumn(0).setMaxWidth(25) self.checksTable.getColumnModel().getColumn(2).setMaxWidth(60) def activate_error_tab(self, status): if status: if self.tabbedPane.getTabCount() == 1: self.tabbedPane.addTab(self.app.strings.getString("Fix"), None, self.panel2, self.app.strings.getString("fix_tab")) else: if self.tabbedPane.getTabCount() == 2: self.tabbedPane.remove(1) def update_checks_buttons(self): """This method sets the status of downloadBtn and startBtn """ #none check selected if len(self.app.selectedChecks) == 0: self.downloadBtn.setEnabled(False) self.startBtn.setEnabled(False) else: #some check selected self.downloadBtn.setEnabled(True) if len(self.app.selectedChecks) > 1: self.startBtn.setEnabled(False) else: #only one check is selected self.app.errors = self.app.selectedChecks[0].errors if self.app.errors is None or len(self.app.errors) == 0: #errors file has not been downloaded and parsed yet self.startBtn.setEnabled(False) else: #errors file has been downloaded and parsed if self.app.selectedChecks[0].toDo == 0: #all errors have been corrected self.startBtn.setEnabled(False) else: self.startBtn.setEnabled(True) #self.nextBtn.setEnabled(True) def update_error_buttons(self, mode): """This method sets the status of: ignoreBtn, falsePositiveBtn, correctedBtn, nextBtn """ if mode == "new error": status = True else: status = False if self.app.selectedChecks[0].tool.fixedFeedbackMode is None: self.correctedBtn.setEnabled(False) else: self.correctedBtn.setEnabled(status) if self.app.selectedChecks[0].tool.falseFeedbackMode is None: self.notErrorBtn.setEnabled(False) else: self.notErrorBtn.setEnabled(status) self.errorInfoBtn.setEnabled(status) self.ignoreBtn.setEnabled(status) if mode in ("reset", "review end"): self.nextBtn.setEnabled(False) elif mode in ("errors downloaded", "show stats", "new error"): self.nextBtn.setEnabled(True) def update_text_fields(self, mode, errorInfo=""): """This method updates the text in: checksTextFld, errorDesc, errorTextFld """ self.errorDesc.text = "" if mode == "review end": cheksTextColor = "green" checksText = self.app.strings.getString("All_errors_reviewed.") errorText = self.app.strings.getString("All_errors_reviewed.") elif mode == "reset": cheksTextColor = "default" checksText = "" errorText = "" elif mode == "show stats": cheksTextColor = "default" checksText = "%s %d / %s" % ( self.app.strings.getString("to_do"), self.app.selectedChecks[0].toDo, len(self.app.selectedChecks[0].errors)) #print "checks text", checksText errorText = "%s%s %d / %s" % ( errorInfo, self.app.strings.getString("to_do"), self.app.selectedChecks[0].toDo, len(self.app.selectedChecks[0].errors)) #print "error text", errorText if self.app.selectedError is not None and self.app.selectedError.desc != "": self.errorDesc.text = "<html>%s</html>" % self.app.selectedError.desc self.set_checksTextFld_color(cheksTextColor) self.checksTextFld.text = checksText self.errorTextFld.text = errorText self.update_statsPanel_status() def update_statsPanel_status(self): if self.checksTextFld.text == "" and not self.app.favouriteZoneStatus: self.statsPanel.setVisible(False) else: self.statsPanel.setVisible(True)
def registerExtenderCallbacks(self, callbacks): # keep a reference to our Burp callbacks object self._callbacks = callbacks # obtain an Burp extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("AuthMatrix - v0.5.2") # DB that holds everything users, roles, and messages self._db = MatrixDB() # For saving/loading config self._fc = JFileChooser() # Used by ActionListeners selfExtender = self self._selectedColumn = -1 self._selectedRow = -1 # Table of User entries self._userTable = UserTable(self, model = UserTableModel(self._db)) roleScrollPane = JScrollPane(self._userTable) self._userTable.redrawTable() # Table of Request (AKA Message) entries self._messageTable = MessageTable(self, model = MessageTableModel(self._db)) messageScrollPane = JScrollPane(self._messageTable) self._messageTable.redrawTable() # Semi-Generic Popup stuff def addPopup(component, popup): class genericMouseListener(MouseAdapter): def mousePressed(self, e): if e.isPopupTrigger(): self.showMenu(e) def mouseReleased(self, e): if e.isPopupTrigger(): self.showMenu(e) def showMenu(self, e): if type(component) is JTableHeader: table = component.getTable() column = component.columnAtPoint(e.getPoint()) if type(table) is MessageTable and column >= selfExtender._db.STATIC_MESSAGE_TABLE_COLUMN_COUNT or type(table) is UserTable and column >= selfExtender._db.STATIC_USER_TABLE_COLUMN_COUNT: selfExtender._selectedColumn = column else: return else: selfExtender._selectedRow = component.rowAtPoint(e.getPoint()) popup.show(e.getComponent(), e.getX(), e.getY()) component.addMouseListener(genericMouseListener()) class actionRunMessage(ActionListener): def actionPerformed(self,e): if selfExtender._selectedRow >= 0: if selfExtender._selectedRow not in selfExtender._messageTable.getSelectedRows(): indexes = [selfExtender._db.getMessageByRow(selfExtender._selectedRow)._index] else: indexes = [selfExtender._db.getMessageByRow(rowNum)._index for rowNum in selfExtender._messageTable.getSelectedRows()] t = Thread(target=selfExtender.runMessagesThread, args = [indexes]) t.start() selfExtender._selectedColumn = -1 # Redrawing the table happens in colorcode within the thread class actionRemoveMessage(ActionListener): def actionPerformed(self,e): if selfExtender._selectedRow >= 0: if selfExtender._selectedRow not in selfExtender._messageTable.getSelectedRows(): indexes = [selfExtender._db.getMessageByRow(selfExtender._selectedRow)._index] else: indexes = [selfExtender._db.getMessageByRow(rowNum)._index for rowNum in selfExtender._messageTable.getSelectedRows()] for i in indexes: selfExtender._db.deleteMessage(i) selfExtender._selectedColumn = -1 selfExtender._messageTable.redrawTable() class actionRemoveUser(ActionListener): def actionPerformed(self,e): if selfExtender._selectedRow >= 0: if selfExtender._selectedRow not in selfExtender._userTable.getSelectedRows(): indexes = [selfExtender._db.getUserByRow(selfExtender._selectedRow)._index] else: indexes = [selfExtender._db.getUserByRow(rowNum)._index for rowNum in selfExtender._userTable.getSelectedRows()] for i in indexes: selfExtender._db.deleteUser(i) selfExtender._selectedColumn = -1 selfExtender._userTable.redrawTable() # TODO combine these next two classes class actionRemoveRoleHeaderFromMessageTable(ActionListener): def actionPerformed(self,e): if selfExtender._selectedColumn >= 0: selfExtender._db.deleteRole(selfExtender._db.getRoleByMessageTableColumn(selfExtender._selectedColumn)._index) selfExtender._selectedColumn = -1 selfExtender._userTable.redrawTable() selfExtender._messageTable.redrawTable() class actionRemoveRoleHeaderFromUserTable(ActionListener): def actionPerformed(self,e): if selfExtender._selectedColumn >= 0: selfExtender._db.deleteRole(selfExtender._db.getRoleByUserTableColumn(selfExtender._selectedColumn)._index) selfExtender._selectedColumn = -1 selfExtender._userTable.redrawTable() selfExtender._messageTable.redrawTable() # Message Table popups messagePopup = JPopupMenu() addPopup(self._messageTable,messagePopup) messageRun = JMenuItem("Run Request(s)") messageRun.addActionListener(actionRunMessage()) messagePopup.add(messageRun) messageRemove = JMenuItem("Remove Request(s)") messageRemove.addActionListener(actionRemoveMessage()) messagePopup.add(messageRemove) messageHeaderPopup = JPopupMenu() addPopup(self._messageTable.getTableHeader(),messageHeaderPopup) roleRemoveFromMessageTable = JMenuItem("Remove Role") roleRemoveFromMessageTable.addActionListener(actionRemoveRoleHeaderFromMessageTable()) messageHeaderPopup.add(roleRemoveFromMessageTable) # User Table popup userPopup = JPopupMenu() addPopup(self._userTable,userPopup) userRemove = JMenuItem("Remove Users(s)") userRemove.addActionListener(actionRemoveUser()) userPopup.add(userRemove) userHeaderPopup = JPopupMenu() addPopup(self._userTable.getTableHeader(),userHeaderPopup) roleRemoveFromUserTable = JMenuItem("Remove Role") roleRemoveFromUserTable.addActionListener(actionRemoveRoleHeaderFromUserTable()) userHeaderPopup.add(roleRemoveFromUserTable) # Top pane topPane = JSplitPane(JSplitPane.VERTICAL_SPLIT,roleScrollPane,messageScrollPane) # request tabs added to this tab on click in message table self._tabs = JTabbedPane() # Button pannel buttons = JPanel() runButton = JButton("Run", actionPerformed=self.runClick) newUserButton = JButton("New User", actionPerformed=self.getInputUserClick) newRoleButton = JButton("New Role", actionPerformed=self.getInputRoleClick) #debugButton = JButton("Debug", actionPerformed=self.printDB) saveButton = JButton("Save", actionPerformed=self.saveClick) loadButton = JButton("Load", actionPerformed=self.loadClick) clearButton = JButton("Clear", actionPerformed=self.clearClick) buttons.add(runButton) buttons.add(newUserButton) buttons.add(newRoleButton) #buttons.add(debugButton) buttons.add(saveButton) buttons.add(loadButton) buttons.add(clearButton) bottomPane = JSplitPane(JSplitPane.VERTICAL_SPLIT, self._tabs, buttons) # Main Pane self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT, topPane, bottomPane) # customize our UI components callbacks.customizeUiComponent(self._splitpane) callbacks.customizeUiComponent(topPane) callbacks.customizeUiComponent(bottomPane) callbacks.customizeUiComponent(messageScrollPane) callbacks.customizeUiComponent(roleScrollPane) callbacks.customizeUiComponent(self._messageTable) callbacks.customizeUiComponent(self._userTable) callbacks.customizeUiComponent(self._tabs) callbacks.customizeUiComponent(buttons) self._splitpane.setResizeWeight(0.5) topPane.setResizeWeight(0.3) bottomPane.setResizeWeight(0.95) # Handles checkbox color coding # Must be bellow the customizeUiComponent calls self._messageTable.setDefaultRenderer(Boolean, SuccessBooleanRenderer(self._db)) # add the custom tab to Burp's UI callbacks.addSuiteTab(self) # register SendTo option callbacks.registerContextMenuFactory(self) return
def __init__(self, actions=[], restore=None, proxy=None, http_mutator=None, texteditor_factory=None, requests=None, stub_responses=None): self._requests = requests if requests is not None else {} self._stub_responses = stub_responses if stub_responses is not None else {} self._actions = actions self._load_headers = [] self._run_config = [['Proxy', proxy], ['Authorization Key', None], ['Load Placeholders', True], ['Generate HTML DOC', True], ['Generate Schema DOC', False], ['Generate Stub Queries', True], ['Accept Invalid SSL Certificate', True], ['Generate Cycles Report', False], ['Cycles Report Timeout', 60], ['Generate TSV', False]] self._init_config = json.loads(json.dumps(self._run_config)) self._default_config = {} for k, v in self._run_config: self._default_config[k] = v self._old_config_hash = None self._actions.insert(0, BrowserAction()) self._actions.insert( 0, ExecutorAction("Configure", lambda _: self._setup())) self._actions.insert(0, ExecutorAction("Load", self._loadurl)) self._http_mutator = http_mutator self.this = JPanel() self.this.setLayout(BorderLayout()) self._omnibar = Omnibar(hint=DEFAULT_LOAD_URL, label="Load", action=self._loadurl) self.this.add(BorderLayout.PAGE_START, self._omnibar.this) self._fileview = FileView( dir=os.getcwd(), filetree_label="Queries, Mutations and Subscriptions", texteditor_factory=texteditor_factory) self.this.add(BorderLayout.CENTER, self._fileview.this) self._fileview.addTreeListener(self._tree_listener) self._fileview.addPayloadListener(self._payload_listener) self._popup = JPopupMenu() self.this.setComponentPopupMenu(self._popup) inherits_popup_menu(self.this) for action in self._actions: self._popup.add(action.menuitem) self._state = {'runs': []} try: if restore: cfg = json.loads(restore) if 'runs' in cfg: for target, key, proxy, headers, load_placeholer, generate_html, generate_schema, generate_queries, generate_cycles, cycles_timeout, generate_tsv, accept_invalid_certificate, flag in cfg[ 'runs']: self._run(target=target, key=key, proxy=proxy, headers=headers, load_placeholer=load_placeholer, generate_html=generate_html, generate_schema=generate_schema, generate_queries=generate_queries, generate_cycles=generate_cycles, cycles_timeout=cycles_timeout, generate_tsv=generate_tsv, accept_invalid_certificate= accept_invalid_certificate, flag=flag) self._run_config = cfg['config'] except Exception as ex: print( "Cannot Load old configuration: starting with a clean state: %s" % ex) sys.stdout.flush() self._state['config'] = self._run_config
class DataViewComponent(JPanel, MouseListener, MouseWheelListener, MouseMotionListener, ActionListener): #hover_border=BorderFactory.createLineBorder(Color.black,2); #item_hover_border=BorderFactory.createLineBorder(Color(0.5,0.5,0.5),1); hover_border = RoundedBorder(Color.black, thickness=2) item_hover_border = RoundedBorder(Color(0.7, 0.7, 0.7)) default_border = BorderFactory.createEmptyBorder() def __init__(self, label=None): JPanel.__init__(self) self.addMouseListener(self) self.addMouseWheelListener(self) self.addMouseMotionListener(self) self.hover = False self.min_width = 20 self.min_height = 20 self.resize_border = 20 self.max_show_dim = 30 # The maximum number of display dimensions to show in the popup menu self.setSize(100, 50) self.border = self.default_border self.popup = JPopupMenu() self.popup.add(JMenuItem('hide', actionPerformed=self.hideme)) self.show_label = False self.label = label self.label_offset = 0 if self.label is not None: self.show_label = True self.popup.add(JPopupMenu.Separator()) self.popup_label = JCheckBoxMenuItem('label', self.show_label, actionPerformed=self.toggle_label) self.popup.add(self.popup_label) self.label_height = 15 self.update_label() else: self.label_height = 0 def save(self): return dict(x=self.x, y=self.y, width=self.width, height=self.height, label=self.show_label) def restore(self, d): self.setLocation(d['x'], d['y']) self.setSize(d['width'], d['height']) self.show_label = d.get('label', False) if self.label is not None: self.popup_label.state = self.show_label self.label_offset = self.label_height * self.show_label def do_hide(self): parent = self.parent self.visible = False if self.parent is not None: self.parent.remove(self) parent.repaint() def hideme(self, event): if event.actionCommand == 'hide': self.do_hide() def toggle_label(self, event): self.show_label = event.source.state self.update_label() def update_label(self): if(self.show_label): self.setLocation(self.x, self.y - self.label_height) self.setSize(self.size.width, self.size.height + self.label_height) self.label_offset = self.label_height else: self.setLocation(self.x, self.y + self.label_height) self.setSize(self.size.width, self.size.height - self.label_height) self.label_offset = 0 self.repaint() def mouseWheelMoved(self, event): delta = event.wheelRotation scale = 0.9 if delta < 0: scale = 1.0 / scale delta = -delta w = self.size.width h = self.size.height for i in range(delta): w *= scale h *= scale if w < self.min_width: w = self.min_width if h < self.min_height: h = self.min_height w = int(w) h = int(h) self.setLocation(int(self.x - (w - self.size.width) / 2), int(self.y - (h - self.size.height) / 2)) self.setSize(w, h) def mouseClicked(self, event): if event.button == MouseEvent.BUTTON3 or (event.button == MouseEvent.BUTTON1 and event.isControlDown()): self.parent.add(self.popup) self.popup.show(self, event.x - 5, event.y - 5) def mouseEntered(self, event): self.border = self.hover_border for n in self.view.area.components: if n is not self and hasattr(n, 'name') and n.name == self.name: n.border = n.item_hover_border self.repaint() def mouseExited(self, event): self.border = self.default_border for n in self.view.area.components: if n is not self and hasattr(n, 'name') and n.name == self.name: n.border = n.default_border self.repaint() def mousePressed(self, event): self.mouse_pressed_x = event.x self.mouse_pressed_y = event.y self.mouse_pressed_size = self.size def mouseReleased(self, event): pass def mouseDragged(self, event): if self.cursor.type == Cursor.HAND_CURSOR: self.setLocation(self.x + event.x - self.mouse_pressed_x, self.y + event.y - self.mouse_pressed_y) if self.cursor.type in [Cursor.W_RESIZE_CURSOR, Cursor.NW_RESIZE_CURSOR, Cursor.SW_RESIZE_CURSOR]: w = self.size.width - event.x + self.mouse_pressed_x if w < self.min_width: w = self.min_width self.setLocation(self.x - w + self.size.width, self.y) self.setSize(w, self.size.height) if self.cursor.type in [Cursor.E_RESIZE_CURSOR, Cursor.NE_RESIZE_CURSOR, Cursor.SE_RESIZE_CURSOR]: w = self.mouse_pressed_size.width + event.x - self.mouse_pressed_x if w < self.min_width: w = self.min_width self.setSize(w, self.size.height) if self.cursor.type in [Cursor.N_RESIZE_CURSOR, Cursor.NW_RESIZE_CURSOR, Cursor.NE_RESIZE_CURSOR]: h = self.size.height - event.y + self.mouse_pressed_y if h < self.min_height: h = self.min_height self.setLocation(self.x, self.y - h + self.size.height) self.setSize(self.size.width, h) if self.cursor.type in [Cursor.S_RESIZE_CURSOR, Cursor.SW_RESIZE_CURSOR, Cursor.SE_RESIZE_CURSOR]: h = self.mouse_pressed_size.height + event.y - self.mouse_pressed_y if h < self.min_height: h = self.min_height self.setSize(self.size.width, h) self.view.area.repaint() def mouseMoved(self, event): size = self.resize_border if event.x < size: if event.y < size: self.cursor = Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR) elif event.y >= self.size.height - size: self.cursor = Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR) else: self.cursor = Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR) elif event.x >= self.size.width - size: if event.y < size: self.cursor = Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR) elif event.y >= self.size.height - size: self.cursor = Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR) else: self.cursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR) else: if event.y < size: self.cursor = Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR) elif event.y >= self.size.height - size: self.cursor = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR) else: self.cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR) def paintComponent(self, g): #if self.hover: # g.color=Color(0.9,0.9,0.9) # g.fillRect(0,0,self.size.width,self.size.height) #else: g.color = Color.white g.fillRect(0, 0, self.size.width, self.size.height) g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) if self.show_label: g.color = Color(0.3, 0.3, 0.3) bounds = g.font.getStringBounds(self.label, g.fontRenderContext) g.drawString(self.label, self.size.width / 2 - bounds.width / 2, bounds.height) def tick(self, t): """This method will be called in the simulation timescale (as opposed to the rendering timescale of paintComponent). This is useful for updating the data that will be displayed by paintComponent, since the data changes at the simulation timescale. Note however that this method is not guaranteed to be called every simulation timestep; for example, if the simulation is running very quickly, it would not be desirable to be updating the data far more quickly than it can be displayed. :param float t: the current simulation time""" pass
class BurpExtender(IBurpExtender, ITab, IMessageEditorController, AbstractTableModel, IContextMenuFactory): def registerExtenderCallbacks(self, callbacks): # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("PT Vulnerabilities Manager") self.config = SafeConfigParser() self.createSection('projects') self.createSection('general') self.config.read('config.ini') self.chooser = JFileChooser() # create the log and a lock on which to synchronize when adding log entries self._log = ArrayList() self._lock = Lock() self.logTable = Table(self) self.logTable.getColumnModel().getColumn(0).setMaxWidth(35) self.logTable.getColumnModel().getColumn(1).setMinWidth(100) self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self.initVulnerabilityTab() self.initProjSettingsTab() self.initTabs() self.initCallbacks() if self.projPath.getText() != None: self.loadVulnerabilities(self.projPath.getText()) print "Thank you for installing PT Vulnerabilities Manager v1.0 extension" print "by Barak Tawily\n\n\n" print "Disclaimer:\nThis extension might create folders and files in your hardisk which might be declared as sensitive information, make sure you are creating projects under encrypted partition" return def initVulnerabilityTab(self): # ## init vulnerability tab # nameLabel = JLabel("Vulnerability Name:") nameLabel.setBounds(10, 10, 140, 30) self.addButton = JButton("Add",actionPerformed=self.addVuln) self.addButton.setBounds(10, 500, 100, 30) rmVulnButton = JButton("Remove",actionPerformed=self.rmVuln) rmVulnButton.setBounds(465, 500, 100, 30) mitigationLabel = JLabel("Mitigation:") mitigationLabel.setBounds(10, 290, 150, 30) addSSBtn = JButton("Add SS",actionPerformed=self.addSS) addSSBtn.setBounds(750, 40, 110, 30) deleteSSBtn = JButton("Remove SS",actionPerformed=self.removeSS) deleteSSBtn.setBounds(750, 75, 110, 30) piclistLabel = JLabel("Images list:") piclistLabel.setBounds(580, 10, 140, 30) self.screenshotsList = DefaultListModel() self.ssList = JList(self.screenshotsList) self.ssList.setBounds(580, 40, 150, 250) self.ssList.addListSelectionListener(ssChangedHandler(self)) self.ssList.setBorder(BorderFactory.createLineBorder(Color.GRAY)) previewPicLabel = JLabel("Selected image preview: (click to open in image viewer)") previewPicLabel.setBounds(580, 290, 500, 30) copyImgMenu = JMenuItem("Copy") copyImgMenu.addActionListener(copyImg(self)) self.imgMenu = JPopupMenu("Popup") self.imgMenu.add(copyImgMenu) self.firstPic = JLabel() self.firstPic.setBorder(BorderFactory.createLineBorder(Color.GRAY)) self.firstPic.setBounds(580, 320, 550, 400) self.firstPic.addMouseListener(imageClicked(self)) self.vulnName = JTextField("") self.vulnName.getDocument().addDocumentListener(vulnTextChanged(self)) self.vulnName.setBounds(140, 10, 422, 30) sevirities = ["Unclassified", "Critical","High","Medium","Low"] self.threatLevel = JComboBox(sevirities); self.threatLevel.setBounds(140, 45, 140, 30) colors = ["Color:", "Green", "Red"] self.colorCombo = JComboBox(colors); self.colorCombo.setBounds(465, 45, 100, 30) self.colorCombo severityLabel = JLabel("Threat Level:") severityLabel.setBounds(10, 45, 100, 30) descriptionLabel = JLabel("Description:") descriptionLabel.setBounds(10, 80, 100, 30) self.descriptionString = JTextArea("", 5, 30) self.descriptionString.setWrapStyleWord(True); self.descriptionString.setLineWrap(True) self.descriptionString.setBounds(10, 110, 555, 175) descriptionStringScroll = JScrollPane(self.descriptionString) descriptionStringScroll.setBounds(10, 110, 555, 175) descriptionStringScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED) self.mitigationStr = JTextArea("", 5, 30) self.mitigationStr.setWrapStyleWord(True); self.mitigationStr.setLineWrap(True) self.mitigationStr.setBounds(10, 320, 555, 175) mitigationStrScroll = JScrollPane(self.mitigationStr) mitigationStrScroll.setBounds(10, 320, 555, 175) mitigationStrScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED) self.pnl = JPanel() self.pnl.setBounds(0, 0, 1000, 1000); self.pnl.setLayout(None); self.pnl.add(addSSBtn) self.pnl.add(piclistLabel) self.pnl.add(nameLabel) self.pnl.add(deleteSSBtn) self.pnl.add(rmVulnButton) self.pnl.add(severityLabel) self.pnl.add(mitigationLabel) self.pnl.add(descriptionLabel) self.pnl.add(previewPicLabel) self.pnl.add(mitigationStrScroll) self.pnl.add(descriptionStringScroll) self.pnl.add(self.ssList) self.pnl.add(self.firstPic) self.pnl.add(self.addButton) self.pnl.add(self.vulnName) self.pnl.add(self.threatLevel) self.pnl.add(self.colorCombo) def initProjSettingsTab(self): # init project settings projNameLabel = JLabel("Name:") projNameLabel.setBounds(10, 50, 140, 30) self.projName = JTextField("") self.projName.setBounds(140, 50, 320, 30) self.projName.getDocument().addDocumentListener(projTextChanged(self)) detailsLabel = JLabel("Details:") detailsLabel.setBounds(10, 120, 140, 30) reportLabel = JLabel("Generate Report:") reportLabel.setBounds(10, 375, 140, 30) types = ["DOCX","HTML","XLSX"] self.reportType = JComboBox(types) self.reportType.setBounds(10, 400, 140, 30) generateReportButton = JButton("Generate", actionPerformed=self.generateReport) generateReportButton.setBounds(160, 400, 90, 30) self.projDetails = JTextArea("", 5, 30) self.projDetails.setWrapStyleWord(True); self.projDetails.setLineWrap(True) projDetailsScroll = JScrollPane(self.projDetails) projDetailsScroll.setBounds(10, 150, 450, 175) projDetailsScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED) projPathLabel = JLabel("Path:") projPathLabel.setBounds(10, 90, 140, 30) self.projPath = JTextField("") self.projPath.setBounds(140, 90, 320, 30) chooseProjPathButton = JButton("Browse...",actionPerformed=self.chooseProjPath) chooseProjPathButton.setBounds(470, 90, 100, 30) importProjButton = JButton("Import",actionPerformed=self.importProj) importProjButton.setBounds(470, 10, 100, 30) exportProjButton = JButton("Export",actionPerformed=self.exportProj) exportProjButton.setBounds(575, 10, 100, 30) openProjButton = JButton("Open Directory",actionPerformed=self.openProj) openProjButton.setBounds(680, 10, 130, 30) currentProjectLabel = JLabel("Current:") currentProjectLabel.setBounds(10, 10, 140, 30) projects = self.config.options('projects') self.currentProject = JComboBox(projects) self.currentProject.addActionListener(projectChangeHandler(self)) self.currentProject.setBounds(140, 10, 140, 30) self.autoSave = JCheckBox("Auto Save Mode") self.autoSave.setEnabled(False) # implement this feature self.autoSave.setBounds(300, 10, 140, 30) self.autoSave.setToolTipText("Will save any changed value while focus is out") addProjButton = JButton("Add / Update",actionPerformed=self.addProj) addProjButton.setBounds(10, 330, 150, 30) removeProjButton = JButton("Remove Current",actionPerformed=self.rmProj) removeProjButton.setBounds(315, 330, 146, 30) generalOptions = self.config.options('general') if 'default project' in generalOptions: defaultProj = self.config.get('general','default project') self.currentProject.getModel().setSelectedItem(defaultProj) self.projPath.setText(self.config.get('projects',self.currentProject.getSelectedItem())) self.clearProjTab = True self.projectSettings = JPanel() self.projectSettings.setBounds(0, 0, 1000, 1000) self.projectSettings.setLayout(None) self.projectSettings.add(reportLabel) self.projectSettings.add(detailsLabel) self.projectSettings.add(projPathLabel) self.projectSettings.add(addProjButton) self.projectSettings.add(openProjButton) self.projectSettings.add(projNameLabel) self.projectSettings.add(projDetailsScroll) self.projectSettings.add(importProjButton) self.projectSettings.add(exportProjButton) self.projectSettings.add(removeProjButton) self.projectSettings.add(generateReportButton) self.projectSettings.add(chooseProjPathButton) self.projectSettings.add(currentProjectLabel) self.projectSettings.add(self.projPath) self.projectSettings.add(self.autoSave) self.projectSettings.add(self.projName) self.projectSettings.add(self.reportType) self.projectSettings.add(self.currentProject) def initTabs(self): # ## init autorize tabs # self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) colorsMenu = JMenu("Paint") redMenu = JMenuItem("Red") noneMenu = JMenuItem("None") greenMenu = JMenuItem("Green") redMenu.addActionListener(paintChange(self, "Red")) noneMenu.addActionListener(paintChange(self, None)) greenMenu.addActionListener(paintChange(self, "Green")) colorsMenu.add(redMenu) colorsMenu.add(noneMenu) colorsMenu.add(greenMenu) self.menu = JPopupMenu("Popup") self.menu.add(colorsMenu) self.tabs = JTabbedPane() self.tabs.addTab("Request", self._requestViewer.getComponent()) self.tabs.addTab("Response", self._responseViewer.getComponent()) self.tabs.addTab("Vulnerability", self.pnl) self.tabs.addTab("Project Settings", self.projectSettings) self.tabs.setSelectedIndex(2) self._splitpane.setRightComponent(self.tabs) def initCallbacks(self): # ## init callbacks # # customize our UI components self._callbacks.customizeUiComponent(self._splitpane) self._callbacks.customizeUiComponent(self.logTable) self._callbacks.customizeUiComponent(self.scrollPane) self._callbacks.customizeUiComponent(self.tabs) self._callbacks.registerContextMenuFactory(self) # add the custom tab to Burp's UI self._callbacks.addSuiteTab(self) def loadVulnerabilities(self, projPath): self.clearList(None) selected = False for root, dirs, files in os.walk(projPath): # make it go only for dirs for dirName in dirs: xmlPath = projPath+"/"+dirName+"/vulnerability.xml" # xmlPath = xmlPath.replace("/","//") document = self.getXMLDoc(xmlPath) nodeList = document.getDocumentElement().getChildNodes() vulnName = nodeList.item(0).getTextContent() severity = nodeList.item(1).getTextContent() description = nodeList.item(2).getTextContent() mitigation = nodeList.item(3).getTextContent() color = nodeList.item(4).getTextContent() test = vulnerability(vulnName,severity,description,mitigation,color) self._lock.acquire() row = self._log.size() self._log.add(test) self.fireTableRowsInserted(row, row) self._lock.release() if vulnName == self.vulnName.getText(): self.logTable.setRowSelectionInterval(row,row) selected = True if selected == False and self._log.size() > 0: self.logTable.setRowSelectionInterval(0, 0) self.loadVulnerability(self._log.get(0)) def createSection(self, sectioName): self.config.read('config.ini') if not (sectioName in self.config.sections()): self.config.add_section(sectioName) cfgfile = open("config.ini",'w') self.config.write(cfgfile) cfgfile.close() def saveCfg(self): f = open('config.ini', 'w') self.config.write(f) f.close() def getXMLDoc(self, xmlPath): try: document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlPath) return document except: self._extender.popup("XML file not found") return def saveXMLDoc(self, doc, xmlPath): transformerFactory = TransformerFactory.newInstance() transformer = transformerFactory.newTransformer() source = DOMSource(doc) result = StreamResult(File(xmlPath)) transformer.transform(source, result) def generateReport(self,event): if self.reportType.getSelectedItem() == "HTML": path = self.reportToHTML() if self.reportType.getSelectedItem() == "XLSX": path = self.reportToXLS() if self.reportType.getSelectedItem() == "DOCX": path = self.generateReportFromDocxTemplate('template.docx',"newfile.docx", 'word/document.xml') n = JOptionPane.showConfirmDialog(None, "Report generated successfuly:\n%s\nWould you like to open it?" % (path), "PT Manager", JOptionPane.YES_NO_OPTION) if n == JOptionPane.YES_OPTION: os.system('"' + path + '"') # Bug! stucking burp until the file get closed def exportProj(self,event): self.chooser.setDialogTitle("Save project") Ffilter = FileNameExtensionFilter("Zip files", ["zip"]) self.chooser.setFileFilter(Ffilter) returnVal = self.chooser.showSaveDialog(None) if returnVal == JFileChooser.APPROVE_OPTION: dst = str(self.chooser.getSelectedFile()) shutil.make_archive(dst,"zip",self.getCurrentProjPath()) self.popup("Project export successfuly") def importProj(self,event): self.chooser.setDialogTitle("Select project zip to directory") Ffilter = FileNameExtensionFilter("Zip files", ["zip"]) self.chooser.setFileFilter(Ffilter) returnVal = self.chooser.showOpenDialog(None) if returnVal == JFileChooser.APPROVE_OPTION: zipPath = str(self.chooser.getSelectedFile()) self.chooser.setDialogTitle("Select project directory") self.chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY) returnVal = self.chooser.showOpenDialog(None) if returnVal == JFileChooser.APPROVE_OPTION: projPath = str(self.chooser.getSelectedFile()) + "/PTManager" with zipfile.ZipFile(zipPath, "r") as z: z.extractall(projPath) xmlPath = projPath + "/project.xml" document = self.getXMLDoc(xmlPath) nodeList = document.getDocumentElement().getChildNodes() projName = nodeList.item(0).getTextContent() nodeList.item(1).setTextContent(projPath) self.saveXMLDoc(document, xmlPath) self.config.set('projects', projName, projPath) self.saveCfg() self.reloadProjects() self.currentProject.getModel().setSelectedItem(projName) self.clearVulnerabilityTab() def reportToXLS(self): if not xlsxwriterImported: self.popup("xlsxwriter library is not imported") return workbook = xlsxwriter.Workbook(self.getCurrentProjPath() + '/PT Manager Report.xlsx') worksheet = workbook.add_worksheet() bold = workbook.add_format({'bold': True}) worksheet.write(0, 0, "Vulnerability Name", bold) worksheet.write(0, 1, "Threat Level", bold) worksheet.write(0, 2, "Description", bold) worksheet.write(0, 3, "Mitigation", bold) row = 1 for i in range(0,self._log.size()): worksheet.write(row, 0, self._log.get(i).getName()) worksheet.write(row, 1, self._log.get(i).getSeverity()) worksheet.write(row, 2, self._log.get(i).getDescription()) worksheet.write(row, 3, self._log.get(i).getMitigation()) row = row + 1 # add requests and images as well workbook.close() return self.getCurrentProjPath() + '/PT Manager Report.xlsx' def reportToHTML(self): htmlContent = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="he" dir="ltr"> <head> <title>PT Manager Report</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style> body { background-repeat: no-repeat; background-attachment: fixed; font-family: Arial,Tahoma,sens-serif; font-size: 13px; margin: auto; } #warpcenter { width: 900px; margin: 0px auto; } table { border: 2px dashed #000000; } td { border-top: 2px dashed #000000; padding: 10px; } img { border: 0px; } </style> <script language="javascript"> function divHideShow(divToHideOrShow) { var div = document.getElementById(divToHideOrShow); if (div.style.display == "block") { div.style.display = "none"; } else { div.style.display = "block"; } } </script> </head> <body> <div id="warpcenter"> <h1> PT Manager Report </h1> <h2> Project: %s</h1> """ % (self.projName.getText()) for i in range(0,self._log.size()): name = self._log.get(i).getName() request = "None" response = "None" path = self.getVulnReqResPath("request",name) if os.path.exists(path): request = self.newlineToBR(self.getFileContent(path)) path = self.getVulnReqResPath("response",name) if os.path.exists(path): response = self.newlineToBR(self.getFileContent(path)) images = "" for fileName in os.listdir(self.projPath.getText()+"/"+self.clearStr(name)): if fileName.endswith(".jpg"): images += "%s<br><img src=\"%s\"><br><br>" % (fileName, self.projPath.getText()+"/"+self.clearStr(name) + "/" + fileName) description = self.newlineToBR(self._log.get(i).getDescription()) mitigation = self.newlineToBR(self._log.get(i).getMitigation()) htmlContent += self.convertVulntoTable(i,name,self._log.get(i).getSeverity(), description,mitigation, request, response, images) htmlContent += "</div></body></html>" f = open(self.getCurrentProjPath() + '/PT Manager Report.html', 'w') f.writelines(htmlContent) f.close() return self.getCurrentProjPath() + '/PT Manager Report.html' def newlineToBR(self,string): return "<br />".join(string.split("\n")) def getFileContent(self,path): f = open(path, "rb") content = f.read() f.close() return content def convertVulntoTable(self, number, name, severity, description, mitigation, request = "None", response = "None", images = "None"): return """<div style="width: 100%%;height: 30px;text-align: center;background-color:#E0E0E0;font-size: 17px;font-weight: bold;color: #000;padding-top: 10px;">%s <a href="javascript:divHideShow('Table_%s');" style="color:#191970">(OPEN / CLOSE)</a></div> <div id="Table_%s" style="display: none;"> <table width="100%%" cellspacing="0" cellpadding="0" style="margin: 0px auto;text-align: left;border-top: 0px;"> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Threat Level: </span> <span style="color:#8b8989">%s</span> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Description</span> <a href="javascript:divHideShow('Table_%s_Command_03');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_03" style="display: none;margin-top: 25px;"> %s </div> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Mitigration</span> <a href="javascript:divHideShow('Table_%s_Command_04');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_04" style="display: none;margin-top: 25px;"> %s <b> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Request</span> <a href="javascript:divHideShow('Table_%s_Command_05');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_05" style="display: none;margin-top: 25px;"> %s <b> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Response</span> <a href="javascript:divHideShow('Table_%s_Command_06');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_06" style="display: none;margin-top: 25px;"> %s <b> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Images</span> <a href="javascript:divHideShow('Table_%s_Command_07');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_07" style="display: none;margin-top: 25px;"> %s <b> </td> </tr> </table> </div><br><br>""" % (name,number,number,severity,number,number,description,number,number,mitigation,number,number,request,number,number,response,number,number,images) def clearVulnerabilityTab(self, rmVuln=True): if rmVuln: self.vulnName.setText("") self.descriptionString.setText("") self.mitigationStr.setText("") self.colorCombo.setSelectedIndex(0) self.threatLevel.setSelectedIndex(0) self.screenshotsList.clear() self.addButton.setText("Add") self.firstPic.setIcon(None) def saveRequestResponse(self, type, requestResponse, vulnName): path = self.getVulnReqResPath(type,vulnName) f = open(path, 'wb') f.write(requestResponse) f.close() def openProj(self, event): os.system('explorer ' + self.projPath.getText()) def getVulnReqResPath(self, requestOrResponse, vulnName): return self.getCurrentProjPath() + "/" + self.clearStr(vulnName) + "/"+requestOrResponse+"_" + self.clearStr(vulnName) def htmlEscape(self,data): return data.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"').replace("'", ''') def generateReportFromDocxTemplate(self, zipname, newZipName, filename): newZipName = self.getCurrentProjPath() + "/" + newZipName with zipfile.ZipFile(zipname, 'r') as zin: with zipfile.ZipFile(newZipName, 'w') as zout: zout.comment = zin.comment for item in zin.infolist(): if item.filename != filename: zout.writestr(item, zin.read(item.filename)) else: xml_content = zin.read(item.filename) result = re.findall("(.*)<w:body>(?:.*)<\/w:body>(.*)",xml_content)[0] newXML = result[0] templateBody = re.findall("<w:body>(.*)<\/w:body>", xml_content)[0] newBody = "" for i in range(0,self._log.size()): tmp = templateBody tmp = tmp.replace("$vulnerability", self.htmlEscape(self._log.get(i).getName())) tmp = tmp.replace("$severity", self.htmlEscape(self._log.get(i).getSeverity())) tmp = tmp.replace("$description", self.htmlEscape(self._log.get(i).getDescription())) tmp = tmp.replace("$mitigation", self.htmlEscape(self._log.get(i).getMitigation())) newBody = newBody + tmp newXML = newXML + newBody newXML = newXML + result[1] with zipfile.ZipFile(newZipName, mode='a', compression=zipfile.ZIP_DEFLATED) as zf: zf.writestr(filename, newXML) return newZipName def chooseProjPath(self, event): self.chooser.setDialogTitle("Select target directory") self.chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY) returnVal = self.chooser.showOpenDialog(None) if returnVal == JFileChooser.APPROVE_OPTION: projPath = str(self.chooser.getSelectedFile()) + "/PTManager" os.makedirs(projPath) self.projPath.setText(projPath) def reloadProjects(self): self.currentProject.setModel(DefaultComboBoxModel(self.config.options('projects'))) def rmProj(self, event): if self.popUpAreYouSure() == JOptionPane.YES_OPTION: self._requestViewer.setMessage("None", False) self._responseViewer.setMessage("None", False) shutil.rmtree(self.projPath.getText()) self.config.remove_option('projects',self.currentProject.getSelectedItem()) self.reloadProjects() self.currentProject.setSelectedIndex(0) self.loadVulnerabilities(self.projPath.getText()) def popup(self,msg): JOptionPane.showMessageDialog(None,msg) def addProj(self, event): projPath = self.projPath.getText() if projPath == None or projPath == "": self.popup("Please select path") return self.config.set('projects', self.projName.getText(), projPath) self.saveCfg() xml = ET.Element('project') name = ET.SubElement(xml, "name") path = ET.SubElement(xml, "path") details = ET.SubElement(xml, "details") autoSaveMode = ET.SubElement(xml, "autoSaveMode") name.text = self.projName.getText() path.text = projPath details.text = self.projDetails.getText() autoSaveMode.text = str(self.autoSave.isSelected()) tree = ET.ElementTree(xml) try: tree.write(self.getCurrentProjPath()+'/project.xml') except: self.popup("Invalid path") return self.reloadProjects() self.clearVulnerabilityTab() self.clearList(None) self.currentProject.getModel().setSelectedItem(self.projName.getText()) def resize(self, image, width, height): bi = BufferedImage(width, height, BufferedImage.TRANSLUCENT) g2d = bi.createGraphics() g2d.addRenderingHints(RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY)) g2d.drawImage(image, 0, 0, width, height, None) g2d.dispose() return bi; def clearStr(self, var): return var.replace(" " , "_").replace("\\" , "").replace("/" , "").replace(":" , "").replace("*" , "").replace("?" , "").replace("\"" , "").replace("<" , "").replace(">" , "").replace("|" , "").replace("(" , "").replace(")" , "") def popUpAreYouSure(self): dialogResult = JOptionPane.showConfirmDialog(None,"Are you sure?","Warning",JOptionPane.YES_NO_OPTION) if dialogResult == 0: return 0 return 1 def removeSS(self,event): if self.popUpAreYouSure() == JOptionPane.YES_OPTION: os.remove(self.getCurrentVulnPath() + "/" + self.ssList.getSelectedValue()) self.ssList.getModel().remove(self.ssList.getSelectedIndex()) self.firstPic.setIcon(ImageIcon(None)) # check if there is images and select the first one # bug in linux def addSS(self,event): clipboard = Toolkit.getDefaultToolkit().getSystemClipboard() try: image = clipboard.getData(DataFlavor.imageFlavor) except: self.popup("Clipboard not contains image") return vulnPath = self.projPath.getText() + "/" + self.clearStr(self.vulnName.getText()) if not os.path.exists(vulnPath): os.makedirs(vulnPath) name = self.clearStr(self.vulnName.getText()) + str(random.randint(1, 99999))+".jpg" fileName = self.projPath.getText()+"/"+ self.clearStr(self.vulnName.getText()) + "/" + name file = File(fileName) bufferedImage = BufferedImage(image.getWidth(None), image.getHeight(None), BufferedImage.TYPE_INT_RGB); g = bufferedImage.createGraphics(); g.drawImage(image, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), Color.WHITE, None); ImageIO.write(bufferedImage, "jpg", file) self.addVuln(self) self.ssList.setSelectedValue(name,True) def rmVuln(self, event): if self.popUpAreYouSure() == JOptionPane.YES_OPTION: self._requestViewer.setMessage("None", False) self._responseViewer.setMessage("None", False) shutil.rmtree(self.getCurrentVulnPath()) self.clearVulnerabilityTab() self.loadVulnerabilities(self.getCurrentProjPath()) def addVuln(self, event): if self.colorCombo.getSelectedItem() == "Color:": colorTxt = None else: colorTxt = self.colorCombo.getSelectedItem() self._lock.acquire() row = self._log.size() vulnObject = vulnerability(self.vulnName.getText(),self.threatLevel.getSelectedItem(),self.descriptionString.getText(),self.mitigationStr.getText() ,colorTxt) self._log.add(vulnObject) self.fireTableRowsInserted(row, row) self._lock.release() vulnPath = self.projPath.getText() + "/" + self.clearStr(self.vulnName.getText()) if not os.path.exists(vulnPath): os.makedirs(vulnPath) xml = ET.Element('vulnerability') name = ET.SubElement(xml, "name") severity = ET.SubElement(xml, "severity") description = ET.SubElement(xml, "description") mitigation = ET.SubElement(xml, "mitigation") color = ET.SubElement(xml, "color") name.text = self.vulnName.getText() severity.text = self.threatLevel.getSelectedItem() description.text = self.descriptionString.getText() mitigation.text = self.mitigationStr.getText() color.text = colorTxt tree = ET.ElementTree(xml) tree.write(vulnPath+'/vulnerability.xml') self.loadVulnerabilities(self.getCurrentProjPath()) self.loadVulnerability(vulnObject) def vulnNameChanged(self): if os.path.exists(self.getCurrentVulnPath()) and self.vulnName.getText() != "": self.addButton.setText("Update") elif self.addButton.getText() != "Add": options = ["Create a new vulnerability", "Change current vulnerability name"] n = JOptionPane.showOptionDialog(None, "Would you like to?", "Vulnerability Name", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, None, options, options[0]); if n == 0: self.clearVulnerabilityTab(False) self.addButton.setText("Add") else: newName = JOptionPane.showInputDialog( None, "Enter new name:", "Vulnerability Name", JOptionPane.PLAIN_MESSAGE, None, None, self.vulnName.getText()) row = self.logTable.getSelectedRow() old = self.logTable.getValueAt(row,1) self.changeVulnName(newName,old) def changeVulnName(self,new,old): newpath = self.getCurrentProjPath() + "/" + new oldpath = self.getCurrentProjPath() + "/" + old os.rename(oldpath,newpath) self.changeCurrentVuln(new,0, newpath + "/vulnerability.xml") def getCurrentVulnPath(self): return self.projPath.getText() + "/" + self.clearStr(self.vulnName.getText()) def getCurrentProjPath(self): return self.projPath.getText() def loadSS(self, imgPath): image = ImageIO.read(File(imgPath)) if image.getWidth() <= 550 and image.getHeight() <= 400: self.firstPic.setIcon(ImageIcon(image)) self.firstPic.setSize(image.getWidth(),image.getHeight()) else: self.firstPic.setIcon(ImageIcon(self.resize(image,550, 400))) self.firstPic.setSize(550,400) def clearProjectTab(self): self.projPath.setText("") self.projDetails.setText("") def clearList(self, event): self._lock.acquire() self._log = ArrayList() row = self._log.size() self.fireTableRowsInserted(row, row) self._lock.release() # # implement IContextMenuFactory # def createMenuItems(self, invocation): responses = invocation.getSelectedMessages(); if responses > 0: ret = LinkedList() requestMenuItem = JMenuItem("Send to PT Manager"); requestMenuItem.addActionListener(handleMenuItems(self,responses[0], "request")) ret.add(requestMenuItem); return(ret); return null; # # implement ITab # def getTabCaption(self): return "PT Manager" def getUiComponent(self): return self._splitpane # # extend AbstractTableModel # def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 3 def getColumnName(self, columnIndex): if columnIndex == 0: return "#" if columnIndex == 1: return "Vulnerability Name" if columnIndex == 2: return "Threat Level" return "" def getValueAt(self, rowIndex, columnIndex): vulnObject = self._log.get(rowIndex) if columnIndex == 0: return rowIndex+1 if columnIndex == 1: return vulnObject.getName() if columnIndex == 2: return vulnObject.getSeverity() if columnIndex == 3: return vulnObject.getMitigation() if columnIndex == 4: return vulnObject.getColor() return "" def changeCurrentVuln(self,value,fieldNumber, xmlPath = "def"): if xmlPath == "def": xmlPath = self.getCurrentVulnPath() + "/vulnerability.xml" document = self.getXMLDoc(xmlPath) nodeList = document.getDocumentElement().getChildNodes() nodeList.item(fieldNumber).setTextContent(value) self.saveXMLDoc(document, xmlPath) self.loadVulnerabilities(self.getCurrentProjPath()) def loadVulnerability(self, vulnObject): self.addButton.setText("Update") self.vulnName.setText(vulnObject.getName()) self.threatLevel.setSelectedItem(vulnObject.getSeverity()) self.descriptionString.setText(vulnObject.getDescription()) self.mitigationStr.setText(vulnObject.getMitigation()) if vulnObject.getColor() == "" or vulnObject.getColor() == None: self.colorCombo.setSelectedItem("Color:") else: self.colorCombo.setSelectedItem(vulnObject.getColor()) self.screenshotsList.clear() for fileName in os.listdir(self.projPath.getText()+"/"+self.clearStr(vulnObject.getName())): if fileName.endswith(".jpg"): self.screenshotsList.addElement(fileName) imgPath = self.projPath.getText()+"/"+self.clearStr(vulnObject.getName())+'/'+fileName # imgPath = imgPath.replace("/","//") self.loadSS(imgPath) if (self.screenshotsList.getSize() == 0): self.firstPic.setIcon(None) else: self.ssList.setSelectedIndex(0) path = self.getVulnReqResPath("request",vulnObject.getName()) if os.path.exists(path): f = self.getFileContent(path) self._requestViewer.setMessage(f, False) else: self._requestViewer.setMessage("None", False) path = self.getVulnReqResPath("response",vulnObject.getName()) if os.path.exists(path): f = self.getFileContent(path) self._responseViewer.setMessage(f, False) else: self._responseViewer.setMessage("None", False)
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, IContextMenuFactory, IExtensionStateListener): # # 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() # set our extension name callbacks.setExtensionName("Burp Scope Monitor Experimental") self.GLOBAL_HANDLER_ANALYZED = False self.GLOBAL_HANDLER = False self.STATUS = False self.AUTOSAVE_REQUESTS = 10 self.AUTOSAVE_TIMEOUT = 600 # 10 minutes should be fine self.CONFIG_INSCOPE = True self.BAD_EXTENSIONS_DEFAULT = [ '.gif', '.png', '.js', '.woff', '.woff2', '.jpeg', '.jpg', '.css', '.ico', '.m3u8', '.ts', '.svg' ] self.BAD_MIMES_DEFAULT = [ 'gif', 'script', 'jpeg', 'jpg', 'png', 'video', 'mp2t' ] self.BAD_EXTENSIONS = self.BAD_EXTENSIONS_DEFAULT self.BAD_MIMES = self.BAD_MIMES_DEFAULT # create the log and a lock on which to synchronize when adding log entries self._currentlyDisplayedItem = None self.SELECTED_MODEL_ROW = 0 self.SELECTED_VIEW_ROW = 0 self._log = ArrayList() self._fullLog = ArrayList() self._lock = Lock() self._lockFile = Lock() # main split pane self._parentPane = JTabbedPane() self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT) ##### config pane self._config = JTabbedPane() config = JPanel() iexport = JPanel() #config.setLayout(BorderLayout()) config.setLayout(None) iexport.setLayout(None) # config radio button X_BASE = 40 Y_OFFSET = 5 Y_OPTION = 200 Y_OPTION_SPACING = 20 Y_CHECKMARK_SPACING = 20 self.showAllButton = JRadioButton(SHOW_ALL_BUTTON_LABEL, True) self.showNewButton = JRadioButton(SHOW_NEW_BUTTON_LABEL, False) self.showTestedButton = JRadioButton(SHOW_TEST_BUTTON_LABEL, False) self.showAllButton.setBounds(40, 60 + Y_OFFSET, 400, 30) self.showNewButton.setBounds(40, 80 + Y_OFFSET, 400, 30) self.showTestedButton.setBounds(40, 100 + Y_OFFSET, 400, 30) #self.showNewButton = JRadioButton(SHOW_NEW_BUTTON_LABEL, False) #self.showTestedButton = JRadioButton(SHOW_TEST_BUTTON_LABEL, False) self.showAllButton.addActionListener(self.handleRadioConfig) self.showNewButton.addActionListener(self.handleRadioConfig) self.showTestedButton.addActionListener(self.handleRadioConfig) self.clearButton = JButton("Clear") self.clearButton.addActionListener(self.handleClearButton) self.clearButton.setBounds(40, 20, 100, 30) self.startButton = JButton(MONITOR_ON_LABEL) self.startButton.addActionListener(self.handleStartButton) self.startButton.setBounds(150, 20, 200, 30) self.badExtensionsLabel = JLabel("Ignore extensions:") self.badExtensionsLabel.setBounds(X_BASE, 150, 200, 30) self.badExtensionsText = JTextArea("") self.loadBadExtensions() self.badExtensionsText.setBounds(X_BASE, 175, 310, 30) self.badExtensionsButton = JButton("Save") self.badExtensionsButton.addActionListener( self.handleBadExtensionsButton) self.badExtensionsButton.setBounds(355, 175, 70, 30) self.badExtensionsDefaultButton = JButton("Load Defaults") self.badExtensionsDefaultButton.addActionListener( self.handleBadExtensionsDefaultButton) self.badExtensionsDefaultButton.setBounds(430, 175, 120, 30) self.badMimesLabel = JLabel("Ignore mime types:") self.badMimesLabel.setBounds(X_BASE, 220, 200, 30) self.badMimesText = JTextArea("") self.loadBadMimes() self.badMimesText.setBounds(X_BASE, 245, 310, 30) self.badMimesButton = JButton("Save") self.badMimesButton.addActionListener(self.handleBadMimesButton) self.badMimesButton.setBounds(355, 245, 70, 30) self.badMimesDefaultButton = JButton("Load Defaults") self.badMimesDefaultButton.addActionListener( self.handleBadMimesDefaultButton) self.badMimesDefaultButton.setBounds(430, 245, 120, 30) self.otherLabel = JLabel("Other:") self.otherLabel.setBounds(40, 300, 120, 30) self.otherLabel2 = JLabel("Other:") self.otherLabel2.setBounds(X_BASE, Y_OPTION, 120, 30) self.autoSaveOption = JCheckBox("Auto save periodically") self.autoSaveOption.setSelected(True) self.autoSaveOption.addActionListener(self.handleAutoSaveOption) self.autoSaveOption.setBounds(X_BASE, Y_OPTION + Y_CHECKMARK_SPACING, 420, 30) self.repeaterOptionButton = JCheckBox( "Repeater request automatically marks as analyzed") self.repeaterOptionButton.setSelected(True) self.repeaterOptionButton.addActionListener( self.handleRepeaterOptionButton) self.repeaterOptionButton.setBounds(50, 330, 420, 30) self.scopeOptionButton = JCheckBox("Follow Burp Target In Scope rules") self.scopeOptionButton.setSelected(True) self.scopeOptionButton.addActionListener(self.handleScopeOptionButton) self.scopeOptionButton.setBounds(50, 350, 420, 30) self.startOptionButton = JCheckBox("Autostart Scope Monitor") self.startOptionButton.setSelected(True) self.startOptionButton.addActionListener(self.handleStartOption) self.startOptionButton.setBounds(50, 350 + Y_OPTION_SPACING, 420, 30) self.markTestedRequestsProxy = JCheckBox( "Color request in Proxy tab if analyzed") self.markTestedRequestsProxy.setSelected(True) self.markTestedRequestsProxy.addActionListener( self.handleTestedRequestsProxy) self.markTestedRequestsProxy.setBounds(50, 350 + Y_OPTION_SPACING * 2, 420, 30) self.markNotTestedRequestsProxy = JCheckBox( "Color request in Proxy tab if NOT analyzed") self.markNotTestedRequestsProxy.setSelected(True) self.markNotTestedRequestsProxy.addActionListener( self.handleNotTestedRequestsProxy) self.markNotTestedRequestsProxy.setBounds(50, 350 + Y_OPTION_SPACING * 3, 420, 30) self.saveButton = JButton("Save now") self.saveButton.addActionListener(self.handleSaveButton) self.saveButton.setBounds(X_BASE + 320, 95, 90, 30) self.loadButton = JButton("Load now") self.loadButton.addActionListener(self.handleLoadButton) self.loadButton.setBounds(X_BASE + 420, 95, 90, 30) self.selectPath = JButton("Select path") self.selectPath.addActionListener(self.selectExportFile) self.selectPath.setBounds(X_BASE + 530, 60, 120, 30) self.selectPathText = JTextArea("") self.selectPathText.setBounds(X_BASE, 60, 510, 30) self.selectPathLabel = JLabel("State file:") self.selectPathLabel.setBounds(X_BASE, 30, 200, 30) bGroup = ButtonGroup() bGroup.add(self.showAllButton) bGroup.add(self.showNewButton) bGroup.add(self.showTestedButton) config.add(self.clearButton) config.add(self.startButton) config.add(self.startOptionButton) config.add(self.showAllButton) config.add(self.showNewButton) config.add(self.showTestedButton) config.add(self.badExtensionsButton) config.add(self.badExtensionsText) config.add(self.badExtensionsLabel) config.add(self.badMimesButton) config.add(self.badMimesText) config.add(self.badMimesLabel) config.add(self.badExtensionsDefaultButton) config.add(self.badMimesDefaultButton) config.add(self.otherLabel) config.add(self.repeaterOptionButton) config.add(self.scopeOptionButton) config.add(self.markTestedRequestsProxy) config.add(self.markNotTestedRequestsProxy) iexport.add(self.saveButton) iexport.add(self.loadButton) iexport.add(self.selectPath) iexport.add(self.selectPathText) iexport.add(self.selectPathLabel) iexport.add(self.otherLabel2) iexport.add(self.autoSaveOption) self._config.addTab("General", config) self._config.addTab("Import/Export", iexport) ##### end config pane self._parentPane.addTab("Monitor", self._splitpane) self._parentPane.addTab("Config", self._config) # table of log entries self.logTable = Table(self) #self.logTable.setDefaultRenderer(self.logTable.getColumnClass(0), ColoredTableCellRenderer(self)) self.logTable.setAutoCreateRowSorter(True) self.logTable.setRowSelectionAllowed(True) renderer = ColoredTableCellRenderer(self) #column = TableColumn(0, 190, renderer, None) print 'Initiating... ' # this could be improved by fetching initial dimensions self.logTable.getColumn("URL").setPreferredWidth(720) # noscope self.logTable.getColumn("URL").setResizable(True) self.logTable.getColumn("Checked").setCellRenderer(renderer) self.logTable.getColumn("Checked").setPreferredWidth(80) self.logTable.getColumn("Checked").setMaxWidth(80) self.logTable.getColumn("Method").setPreferredWidth(120) #self.logTable.getColumn("Method").setMaxWidth(120) self.logTable.getColumn("Method").setResizable(True) self.logTable.getColumn("Time").setPreferredWidth(120) # noscope self.logTable.getColumn("Time").setResizable(True) scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(scrollPane) # tabs with request/response viewers tabs = JTabbedPane() self._requestViewer = callbacks.createMessageEditor(self, False) self._responseViewer = callbacks.createMessageEditor(self, False) tabs.addTab("Request", self._requestViewer.getComponent()) tabs.addTab("Response", self._responseViewer.getComponent()) self._splitpane.setRightComponent(tabs) ## Row sorter shit #self._tableRowSorterAutoProxyAutoAction = CustomTableRowSorter(self.logTable.getModel()) #self.logTable.setRowSorter(self._tableRowSorterAutoProxyAutoAction) markAnalyzedButton = JMenuItem("Mark Requests as Analyzed") markAnalyzedButton.addActionListener(markRequestsHandler(self, True)) markNotAnalyzedButton = JMenuItem("Mark Requests as NOT Analyzed") markNotAnalyzedButton.addActionListener( markRequestsHandler(self, False)) sendRequestMenu = JMenuItem("Send Request to Repeater") sendRequestMenu.addActionListener(sendRequestRepeater(self)) deleteRequestMenu = JMenuItem("Delete request") deleteRequestMenu.addActionListener(deleteRequestHandler(self)) self.menu = JPopupMenu("Popup") self.menu.add(markAnalyzedButton) self.menu.add(markNotAnalyzedButton) self.menu.add(sendRequestMenu) self.menu.add(deleteRequestMenu) # customize our UI components callbacks.customizeUiComponent(self._parentPane) callbacks.customizeUiComponent(self._splitpane) callbacks.customizeUiComponent(self._config) callbacks.customizeUiComponent(config) callbacks.customizeUiComponent(self.logTable) callbacks.customizeUiComponent(scrollPane) callbacks.customizeUiComponent(tabs) callbacks.registerContextMenuFactory(self) callbacks.registerExtensionStateListener(self) callbacks.registerScannerCheck(passiveScanner(self)) # add the custom tab to Burp's UI callbacks.addSuiteTab(self) # register ourselves as an HTTP listener callbacks.registerHttpListener(self) self.loadConfigs() print "Loaded!" print "Experimental import state.. " self.importState("") self.SC = sched.scheduler(time.time, time.sleep) self.SCC = self.SC.enter(10, 1, self.autoSave, (self.SC, )) self.SC.run() return ##### CUSTOM CODE ##### def loadConfigs(self): if self._callbacks.loadExtensionSetting("CONFIG_AUTOSTART") == "False": self.startOptionButton.setSelected(False) self.startOrStop(None, False) else: self.startOptionButton.setSelected(True) self.startOrStop(None, True) if self._callbacks.loadExtensionSetting("exportFile") != "": self.selectPathText.setText( self._callbacks.loadExtensionSetting("exportFile")) if self._callbacks.loadExtensionSetting("CONFIG_REPEATER") == "True": self.repeaterOptionButton.setSelected(True) else: self.repeaterOptionButton.setSelected(False) if self._callbacks.loadExtensionSetting("CONFIG_INSCOPE") == "True": self.scopeOptionButton.setSelected(True) else: self.scopeOptionButton.setSelected(False) if self._callbacks.loadExtensionSetting("CONFIG_AUTOSAVE") == "True": self.autoSaveOption.setSelected(True) else: self.autoSaveOption.setSelected(False) if self._callbacks.loadExtensionSetting( "CONFIG_HIGHLIGHT_TESTED") == "True": self.markTestedRequestsProxy.setSelected(True) else: self.markTestedRequestsProxy.setSelected(False) if self._callbacks.loadExtensionSetting( "CONFIG_HIGHLIGHT_NOT_TESTED") == "True": self.markNotTestedRequestsProxy.setSelected(True) else: self.markNotTestedRequestsProxy.setSelected(False) return def selectExportFile(self, event): parentFrame = JFrame() fileChooser = JFileChooser() fileChooser.setDialogTitle("Specify file to save state") fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY) userSelection = fileChooser.showOpenDialog(parentFrame) if (userSelection == JFileChooser.APPROVE_OPTION): fileLoad = fileChooser.getSelectedFile() filename = fileLoad.getAbsolutePath() self.selectPathText.setText(filename) print 'Filename selected:' + filename self._callbacks.saveExtensionSetting("exportFile", filename) return def extensionUnloaded(self): print 'extension unloading.. ' print 'canceling scheduler.. ' map(self.SC.cancel, self.SC.queue) return def loadBadExtensions(self): bad = self._callbacks.loadExtensionSetting("badExtensions") if bad: self.badExtensionsText.setText(bad) # transform text to array bad = bad.replace(" ", "") self.BAD_EXTENSIONS = bad.split(",") else: print 'no bad extension saved, reverting' self.badExtensionsText.setText(", ".join(self.BAD_EXTENSIONS)) def loadBadMimes(self): bad = self._callbacks.loadExtensionSetting("badMimes") if bad: self.badMimesText.setText(bad) bad = bad.replace(" ", "") self.BAD_MIMES = bad.split(",") else: print 'no bad mimes saved, reverting' self.badMimesText.setText(", ".join(self.BAD_MIMES)) ## GLOBAL CONTEXT CODE ## def createMenuItems(self, invocation): responses = invocation.getSelectedMessages() if responses > 0: ret = LinkedList() analyzedMenuItem = JMenuItem("Mark as analyzed") notAnalyzedMenuItem = JMenuItem("Mark as NOT analyzed") for response in responses: analyzedMenuItem.addActionListener( handleMenuItems(self, response, "analyzed")) notAnalyzedMenuItem.addActionListener( handleMenuItems(self, response, "not")) ret.add(analyzedMenuItem) ret.add(notAnalyzedMenuItem) return ret def getEndpoint(self, requestResponse): url_ = str(self._helpers.analyzeRequest(requestResponse).getUrl()) o = urlparse(url_) url = o.scheme + "://" + o.netloc + o.path #print "Url3: " + url return url def getMethod(self, requestResponse): return self._helpers.analyzeRequest(requestResponse).getMethod() ##### CUSTOM CODE ##### def handleTestedRequestsProxy(self, event): self._callbacks.saveExtensionSetting( "CONFIG_HIGHLIGHT_TESTED", str(self.markTestedRequestsProxy.isSelected())) return def handleNotTestedRequestsProxy(self, event): self._callbacks.saveExtensionSetting( "CONFIG_HIGHLIGHT_NOT_TESTED", str(self.markNotTestedRequestsProxy.isSelected())) return def handleStartOption(self, event): self._callbacks.saveExtensionSetting( "CONFIG_AUTOSTART", str(self.startOptionButton.isSelected())) #print 'saving autostart: ' + str(self.startOptionButton.isSelected()) return def startOrStop(self, event, autoStart): if (self.startButton.getText() == MONITOR_OFF_LABEL) or autoStart: self.startButton.setText(MONITOR_ON_LABEL) self.startButton.setBackground(GREEN_COLOR) self.STATUS = True else: self.startButton.setText(MONITOR_OFF_LABEL) self.startButton.setBackground(RED_COLOR) self.STATUS = False def handleStartButton(self, event): self.startOrStop(event, False) def handleAutoSaveOption(self, event): self._callbacks.saveExtensionSetting( "CONFIG_AUTOSAVE", str(self.autoSaveOption.isSelected())) return def handleSaveButton(self, event): self.exportState("") def handleLoadButton(self, event): self.importState("") def handleRepeaterOptionButton(self, event): self._callbacks.saveExtensionSetting( "CONFIG_REPEATER", str(self.repeaterOptionButton.isSelected())) return def handleScopeOptionButton(self, event): self.CONFIG_INSCOPE = self.scopeOptionButton.isSelected() self._callbacks.saveExtensionSetting("CONFIG_INSCOPE", str(self.CONFIG_INSCOPE)) return def handleBadExtensionsButton(self, event): #print "before BAD array: " print self.BAD_EXTENSIONS extensions = self.badExtensionsText.getText() self._callbacks.saveExtensionSetting("badExtensions", extensions) print 'New extensions blocked: ' + extensions bad = extensions.replace(" ", "") self.BAD_EXTENSIONS = bad.split(",") #print "BAD array: " #print self.BAD_EXTENSIONS def handleBadExtensionsDefaultButton(self, event): self.BAD_EXTENSIONS = self.BAD_EXTENSIONS_DEFAULT self.badExtensionsText.setText(", ".join(self.BAD_EXTENSIONS)) self._callbacks.saveExtensionSetting("badExtensions", ", ".join(self.BAD_EXTENSIONS)) return def handleBadMimesDefaultButton(self, event): self.BAD_MIMES = self.BAD_MIMES_DEFAULT self.badMimesText.setText(", ".join(self.BAD_MIMES)) self._callbacks.saveExtensionSetting("badExtensions", ", ".join(self.BAD_MIMES)) return def handleBadMimesButton(self, event): mimes = self.badMimesText.getText() self._callbacks.saveExtensionSetting("badMimes", mimes) print 'New mimes blocked: ' + mimes bad = mimes.replace(" ", "") self.BAD_MIMES = bad.split(",") def handleClearButton(self, event): print 'Clearing table' self._lock.acquire() self._log = ArrayList() self._fullLog = ArrayList() self._lock.release() return def handleRadioConfig(self, event): #print ' radio button clicked ' #print event.getActionCommand() self._lock.acquire() if event.getActionCommand() == SHOW_ALL_BUTTON_LABEL: print "Showing all" self._log = self._fullLog elif event.getActionCommand() == SHOW_NEW_BUTTON_LABEL: print "Showing new scope only" tmpLog = ArrayList() for item in self._fullLog: if not (item._analyzed): tmpLog.add(item) self._log = tmpLog elif event.getActionCommand() == SHOW_TEST_BUTTON_LABEL: print "Showing tested scope only" tmpLog = ArrayList() for item in self._fullLog: if item._analyzed: tmpLog.add(item) self._log = tmpLog else: print "unrecognized radio label" self.fireTableDataChanged() #self._tableRowSorterAutoProxyAutoAction.toggleSortOrder(1) #self.toggleSortOrder(2) #self.logTable.toggleSortOrder(2) # refresh table? self._lock.release() # # implement ITab # def getTabCaption(self): return "Scope Monitor" def getUiComponent(self): return self._parentPane # # implement IHttpListener # def markAnalyzed(self, messageIsRequest, state): #print "markAnalyzed..." self._lock.acquire() url = self.getEndpoint(messageIsRequest) for item in self._log: if url == item._url: item._analyzed = state self._lock.release() return self._lock.release() return def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): # only process requests #print "processing httpMessage.." #print messageIsRequest print "processHttpMessage toolFlag: " + str(toolFlag) #print " -- " + str(self._callbacks.getToolName(toolFlag)) + " -- " if not (self.STATUS): return #print "global handler status: (true): " + str(self.GLOBAL_HANDLER) #print "(processHTTP) messageIsRequest" #print messageIsRequest isFromPassiveScan = False if toolFlag == 1234: print "1 processHttpMessage: processing passiveScan item" isFromPassiveScan = True if toolFlag != 1234: if messageIsRequest and not (self.GLOBAL_HANDLER): print "1.5 processHttpMessage droping message" return if self.scopeOptionButton.isSelected(): url = self._helpers.analyzeRequest(messageInfo).getUrl() if not self._callbacks.isInScope(url): #print 'Url not in scope, skipping.. ' return #print "still processing httpMessage.., request came from: " + self._callbacks.getToolName(toolFlag) if toolFlag == 1234: print "2 processHttpMessage: processing passiveScan item; setting toolFlag to proxy (4)" toolFlag = 4 #toolFlag = 4 if ((self._callbacks.getToolName(toolFlag) != "Repeater") and (self._callbacks.getToolName(toolFlag) != "Proxy") and (self._callbacks.getToolName(toolFlag) != "Target")): #print 'Aborting processHTTP, request came from: ' + str(self._callbacks.getToolName(toolFlag)) print "Droping request from " + str( self._callbacks.getToolName(toolFlag)) return #print "---> still processing from tool: " + str(self._callbacks.getToolName(toolFlag)) url = self.getEndpoint(messageInfo) method = self.getMethod(messageInfo) #print "(processHTTP) before extensions check: " + url for extension in self.BAD_EXTENSIONS: if url.endswith(extension): return if messageInfo.getResponse(): mime = self._helpers.analyzeResponse( messageInfo.getResponse()).getStatedMimeType() #print 'Declared mime:' + mime mime = mime.lower() if mime in self.BAD_MIMES: #print 'Bad mime:' + mime return #print "[httpMessage] before lock" # create a new log entry with the message details self._lock.acquire() row = self._log.size() for item in self._log: if url == item._url: if method == self._helpers.analyzeRequest( item._requestResponse).getMethod(): #print 'duplicate URL+method, skipping.. ' self._lock.release() # has it been analyzed? analyzed = False if self._callbacks.getToolName(toolFlag) == "Repeater": if self.repeaterOptionButton.isSelected(): analyzed = True #print "[httpMessage] setting analyzed as true" if self.GLOBAL_HANDLER_ANALYZED: analyzed = True item._analyzed = analyzed self.paintItems(messageInfo, item) return #print "[httpMessage] before setComment" if not (isFromPassiveScan): messageInfo.setComment(SCOPE_MONITOR_COMMENT) # reached here, must be new entry analyzed = False if self._callbacks.getToolName(toolFlag) == "Repeater": if self.repeaterOptionButton.isSelected(): analyzed = True #print "[httpMessage] setting analyzed as true" if self.GLOBAL_HANDLER_ANALYZED: analyzed = True #print "[httpMessage] after comment" #print 'in httpmessage, response:' #print self._helpers.analyzeResponse(messageInfo.getResponse()) date = datetime.datetime.fromtimestamp( time.time()).strftime('%H:%M:%S %d %b %Y') entry = LogEntry(toolFlag, self._callbacks.saveBuffersToTempFiles(messageInfo), url, analyzed, date, method) #print "toolFlag: " + str(toolFlag) #print "(processHTTP) Adding URL: " + url self._log.add(entry) self._fullLog.add(entry) self.fireTableRowsInserted(row, row) self.paintItems(messageInfo, entry) self._lock.release() #print "columnCoun:" + str(self.logTable.getColumnCount()) # # extend AbstractTableModel # def paintItems(self, messageInfo, item): ''' print "in paint Items" print "mark color is: (true)" + str(self.markTestedRequestsProxy.isSelected()) print "global handler analyzed: :" + str(self.GLOBAL_HANDLER_ANALYZED) print "item analyzed should be the same ^^:" + str(item._analyzed) ''' if (self.markTestedRequestsProxy.isSelected()) and ( item._analyzed and self.GLOBAL_HANDLER_ANALYZED): messageInfo.setHighlight("green") return if self.markNotTestedRequestsProxy.isSelected() and not ( item._analyzed): messageInfo.setHighlight("red") def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 4 def getColumnName(self, columnIndex): if columnIndex == 0: return "Checked" if columnIndex == 1: return "URL" if columnIndex == 2: return "Method" if columnIndex == 3: return "Time" def getValueAt(self, rowIndex, columnIndex): logEntry = self._log.get(rowIndex) #self.setBackground(Color.GREEN) return self.returnEntry(rowIndex, columnIndex, logEntry) if self.showNewButton.isSelected() and not (logEntry._analyzed): return self.returnEntry(rowIndex, columnIndex, logEntry) elif self.showTestedButton.isSelected() and logEntry._analyzed: return self.returnEntry(rowIndex, columnIndex, logEntry) elif self.showAllButton.isSelected(): return self.returnEntry(rowIndex, columnIndex, logEntry) def returnEntry(self, rowIndex, columnIndex, entry): logEntry = self._log.get(rowIndex) if columnIndex == 0: if logEntry._analyzed: return "True" else: return "False" if columnIndex == 1: return self._helpers.urlDecode(logEntry._url) if columnIndex == 2: return logEntry._method if columnIndex == 3: return logEntry._date # return date 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): #print 'getRequest called' return self._currentlyDisplayedItem.getRequest() def getResponse(self): #print 'getResponse called: ' print self._currentlyDisplayedItem.getResponse() return self._currentlyDisplayedItem.getResponse() def exportRequest(self, entity, filename): line = str(entity._analyzed) + "," line = line + self._helpers.urlEncode(entity._url).replace( ",", "%2c") + "," # URL is encoded so we should be good line = line + entity._method + "," line = line + entity._date line = line + '\n' #print 'Exporting: "' + line + '"' return line def exportUrlEncode(self, url): return self._helpers.urlEncode(url).replace(",", "%2c") def exportState(self, filename): filename = self.selectPathText.getText() if filename == "": filename = self._callbacks.loadExtensionSetting("exportFile") print 'Empty filename, skipping export' return else: self._callbacks.saveExtensionSetting("exportFile", filename) print 'saving state to: ' + filename savedUrls = [] self._lockFile.acquire() try: with open(filename, 'r') as fr: savedEntries = fr.read().splitlines() savedUrls = [] for savedEntry in savedEntries: savedUrls.append(savedEntry.split(",")[1]) #print "savedUrls len: " + str(len(savedUrls)) #print "savedUrls:" #print savedUrls fr.close() except IOError: print "Autosaving skipped as file doesn't exist yet" with open(filename, 'a+') as f: for item in self._log: if self.exportUrlEncode(item._url) not in savedUrls: line = self.exportRequest(item, "xx") f.write(line) f.close() self._lockFile.release() return def importState(self, filename): filename = self.selectPathText.getText() if filename == "": filename = self._callbacks.loadExtensionSetting("exportFile") print 'Empty filename, skipping import' return else: self._callbacks.saveExtensionSetting("exportFile", filename) print 'loading state from: ' + filename self.STATUS = False self._lockFile.acquire() with open(filename, 'r') as f: proxy = self._callbacks.getProxyHistory() proxyItems = [] for item in proxy: if item.getComment(): if SCOPE_MONITOR_COMMENT in item.getComment(): proxyItems.append(item) print 'proxyItems has: ' + str(len(proxyItems)) # TODO - if no proxy items, sraight to import lines = f.read().splitlines() for line in lines: data = line.split(",") url = data[1] url = self._helpers.urlDecode(url) #print 'Saving: ' + url if not self._callbacks.isInScope(URL(url)): print '-- imported url not in scope, skipping.. ' continue analyzed = False if data[0] == "True": analyzed = True #print '.. simulating url search.. ' requestResponse = None for request in proxyItems: if url == self.getEndpoint(request): #print 'Match found when importing for url: ' + url requestResponse = request break self._log.add( LogEntry("", requestResponse, url, analyzed, data[3], data[2])) self._lockFile.release() print 'finished loading.. ' #print 'size: ' + str(self._log.size()) self.fireTableDataChanged() if self.startButton.getText() == MONITOR_ON_LABEL: self.STATUS = True return def autoSave(self, sc): #print 'autosaving.. lol what' if self.autoSaveOption.isSelected(): print "[" + self.getTime( ) + "] autosaving to " + self._callbacks.loadExtensionSetting( "exportFile") self.exportState("") self.SC.enter(self.AUTOSAVE_TIMEOUT, 1, self.autoSave, (self.SC, )) return def getTime(self): date = datetime.datetime.fromtimestamp( time.time()).strftime('%H:%M:%S') return date
def registerExtenderCallbacks(self, callbacks): # keep a reference to our Burp callbacks object self._callbacks = callbacks # obtain an Burp extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("AuthMatrix - v0.4") # DB that holds everything users, roles, and messages self._db = MatrixDB() # For saving/loading config self._fc = JFileChooser() # Used by ActionListeners selfExtender = self self._selectedColumn = -1 self._selectedRow = -1 # Table of User entries self._userTable = UserTable(self, model=UserTableModel(self._db)) roleScrollPane = JScrollPane(self._userTable) self._userTable.redrawTable() # Table of Request (AKA Message) entries self._messageTable = MessageTable(self, model=MessageTableModel(self._db)) messageScrollPane = JScrollPane(self._messageTable) self._messageTable.redrawTable() # Semi-Generic Popup stuff def addPopup(component, popup): class genericMouseListener(MouseAdapter): def mousePressed(self, e): if e.isPopupTrigger(): self.showMenu(e) def mouseReleased(self, e): if e.isPopupTrigger(): self.showMenu(e) def showMenu(self, e): if type(component) is JTableHeader: table = component.getTable() column = component.columnAtPoint(e.getPoint()) if type( table ) is MessageTable and column >= selfExtender._db.STATIC_MESSAGE_TABLE_COLUMN_COUNT or type( table ) is UserTable and column >= selfExtender._db.STATIC_USER_TABLE_COLUMN_COUNT: selfExtender._selectedColumn = column else: return else: selfExtender._selectedRow = component.rowAtPoint( e.getPoint()) popup.show(e.getComponent(), e.getX(), e.getY()) component.addMouseListener(genericMouseListener()) class actionRunMessage(ActionListener): def actionPerformed(self, e): if selfExtender._selectedRow >= 0: if selfExtender._selectedRow not in selfExtender._messageTable.getSelectedRows( ): indexes = [ selfExtender._db.getMessageByRow( selfExtender._selectedRow)._index ] else: indexes = [ selfExtender._db.getMessageByRow(rowNum)._index for rowNum in selfExtender._messageTable.getSelectedRows() ] t = Thread(target=selfExtender.runMessagesThread, args=[indexes]) t.start() selfExtender._selectedColumn = -1 # Redrawing the table happens in colorcode within the thread class actionRemoveMessage(ActionListener): def actionPerformed(self, e): if selfExtender._selectedRow >= 0: if selfExtender._selectedRow not in selfExtender._messageTable.getSelectedRows( ): indexes = [ selfExtender._db.getMessageByRow( selfExtender._selectedRow)._index ] else: indexes = [ selfExtender._db.getMessageByRow(rowNum)._index for rowNum in selfExtender._messageTable.getSelectedRows() ] for i in indexes: selfExtender._db.deleteMessage(i) selfExtender._selectedColumn = -1 selfExtender._messageTable.redrawTable() class actionRemoveUser(ActionListener): def actionPerformed(self, e): if selfExtender._selectedRow >= 0: if selfExtender._selectedRow not in selfExtender._userTable.getSelectedRows( ): indexes = [ selfExtender._db.getUserByRow( selfExtender._selectedRow)._index ] else: indexes = [ selfExtender._db.getUserByRow(rowNum)._index for rowNum in selfExtender._userTable.getSelectedRows() ] for i in indexes: selfExtender._db.deleteUser(i) selfExtender._selectedColumn = -1 selfExtender._userTable.redrawTable() # TODO combine these next two classes # TODO Also, clean up the variable names where M and U are in place of MessageTable and UserTable class actionRemoveRoleHeaderFromM(ActionListener): def actionPerformed(self, e): if selfExtender._selectedColumn >= 0: selfExtender._db.deleteRole( selfExtender._db.getRoleByMColumn( selfExtender._selectedColumn)._index) selfExtender._selectedColumn = -1 selfExtender._userTable.redrawTable() selfExtender._messageTable.redrawTable() class actionRemoveRoleHeaderFromU(ActionListener): def actionPerformed(self, e): if selfExtender._selectedColumn >= 0: selfExtender._db.deleteRole( selfExtender._db.getRoleByUColumn( selfExtender._selectedColumn)._index) selfExtender._selectedColumn = -1 selfExtender._userTable.redrawTable() selfExtender._messageTable.redrawTable() # Message Table popups messagePopup = JPopupMenu() addPopup(self._messageTable, messagePopup) messageRun = JMenuItem("Run Request(s)") messageRun.addActionListener(actionRunMessage()) messagePopup.add(messageRun) messageRemove = JMenuItem("Remove Request(s)") messageRemove.addActionListener(actionRemoveMessage()) messagePopup.add(messageRemove) messageHeaderPopup = JPopupMenu() addPopup(self._messageTable.getTableHeader(), messageHeaderPopup) roleRemoveFromM = JMenuItem("Remove Role") roleRemoveFromM.addActionListener(actionRemoveRoleHeaderFromM()) messageHeaderPopup.add(roleRemoveFromM) # User Table popup userPopup = JPopupMenu() addPopup(self._userTable, userPopup) userRemove = JMenuItem("Remove Users(s)") userRemove.addActionListener(actionRemoveUser()) userPopup.add(userRemove) userHeaderPopup = JPopupMenu() addPopup(self._userTable.getTableHeader(), userHeaderPopup) roleRemoveFromU = JMenuItem("Remove Role") roleRemoveFromU.addActionListener(actionRemoveRoleHeaderFromU()) userHeaderPopup.add(roleRemoveFromU) # Top pane topPane = JSplitPane(JSplitPane.VERTICAL_SPLIT, roleScrollPane, messageScrollPane) topPane.setResizeWeight(0.3) # request tabs added to this tab on click in message table self._tabs = JTabbedPane() # Button pannel buttons = JPanel() runButton = JButton("Run", actionPerformed=self.runClick) newUserButton = JButton("New User", actionPerformed=self.getInputUserClick) newRoleButton = JButton("New Role", actionPerformed=self.getInputRoleClick) #debugButton = JButton("Debug", actionPerformed=self.printDB) saveButton = JButton("Save", actionPerformed=self.saveClick) loadButton = JButton("Load", actionPerformed=self.loadClick) clearButton = JButton("Clear", actionPerformed=self.clearClick) buttons.add(runButton) buttons.add(newUserButton) buttons.add(newRoleButton) #buttons.add(debugButton) buttons.add(saveButton) buttons.add(loadButton) buttons.add(clearButton) bottomPane = JSplitPane(JSplitPane.VERTICAL_SPLIT, self._tabs, buttons) bottomPane.setResizeWeight(0.95) # Main Pane self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT, topPane, bottomPane) self._splitpane.setResizeWeight(0.5) # customize our UI components callbacks.customizeUiComponent(self._splitpane) callbacks.customizeUiComponent(topPane) callbacks.customizeUiComponent(bottomPane) callbacks.customizeUiComponent(messageScrollPane) callbacks.customizeUiComponent(roleScrollPane) callbacks.customizeUiComponent(self._messageTable) callbacks.customizeUiComponent(self._userTable) callbacks.customizeUiComponent(self._tabs) callbacks.customizeUiComponent(buttons) # Handles checkbox color coding # Must be bellow the customizeUiComponent calls self._messageTable.setDefaultRenderer(Boolean, SuccessBooleanRenderer(self._db)) # add the custom tab to Burp's UI callbacks.addSuiteTab(self) # register SendTo option callbacks.registerContextMenuFactory(self) return
def registerExtenderCallbacks(self, callbacks): # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("Burp Scope Monitor Experimental") self.GLOBAL_HANDLER_ANALYZED = False self.GLOBAL_HANDLER = False self.STATUS = False self.AUTOSAVE_REQUESTS = 10 self.AUTOSAVE_TIMEOUT = 600 # 10 minutes should be fine self.CONFIG_INSCOPE = True self.BAD_EXTENSIONS_DEFAULT = [ '.gif', '.png', '.js', '.woff', '.woff2', '.jpeg', '.jpg', '.css', '.ico', '.m3u8', '.ts', '.svg' ] self.BAD_MIMES_DEFAULT = [ 'gif', 'script', 'jpeg', 'jpg', 'png', 'video', 'mp2t' ] self.BAD_EXTENSIONS = self.BAD_EXTENSIONS_DEFAULT self.BAD_MIMES = self.BAD_MIMES_DEFAULT # create the log and a lock on which to synchronize when adding log entries self._currentlyDisplayedItem = None self.SELECTED_MODEL_ROW = 0 self.SELECTED_VIEW_ROW = 0 self._log = ArrayList() self._fullLog = ArrayList() self._lock = Lock() self._lockFile = Lock() # main split pane self._parentPane = JTabbedPane() self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT) ##### config pane self._config = JTabbedPane() config = JPanel() iexport = JPanel() #config.setLayout(BorderLayout()) config.setLayout(None) iexport.setLayout(None) # config radio button X_BASE = 40 Y_OFFSET = 5 Y_OPTION = 200 Y_OPTION_SPACING = 20 Y_CHECKMARK_SPACING = 20 self.showAllButton = JRadioButton(SHOW_ALL_BUTTON_LABEL, True) self.showNewButton = JRadioButton(SHOW_NEW_BUTTON_LABEL, False) self.showTestedButton = JRadioButton(SHOW_TEST_BUTTON_LABEL, False) self.showAllButton.setBounds(40, 60 + Y_OFFSET, 400, 30) self.showNewButton.setBounds(40, 80 + Y_OFFSET, 400, 30) self.showTestedButton.setBounds(40, 100 + Y_OFFSET, 400, 30) #self.showNewButton = JRadioButton(SHOW_NEW_BUTTON_LABEL, False) #self.showTestedButton = JRadioButton(SHOW_TEST_BUTTON_LABEL, False) self.showAllButton.addActionListener(self.handleRadioConfig) self.showNewButton.addActionListener(self.handleRadioConfig) self.showTestedButton.addActionListener(self.handleRadioConfig) self.clearButton = JButton("Clear") self.clearButton.addActionListener(self.handleClearButton) self.clearButton.setBounds(40, 20, 100, 30) self.startButton = JButton(MONITOR_ON_LABEL) self.startButton.addActionListener(self.handleStartButton) self.startButton.setBounds(150, 20, 200, 30) self.badExtensionsLabel = JLabel("Ignore extensions:") self.badExtensionsLabel.setBounds(X_BASE, 150, 200, 30) self.badExtensionsText = JTextArea("") self.loadBadExtensions() self.badExtensionsText.setBounds(X_BASE, 175, 310, 30) self.badExtensionsButton = JButton("Save") self.badExtensionsButton.addActionListener( self.handleBadExtensionsButton) self.badExtensionsButton.setBounds(355, 175, 70, 30) self.badExtensionsDefaultButton = JButton("Load Defaults") self.badExtensionsDefaultButton.addActionListener( self.handleBadExtensionsDefaultButton) self.badExtensionsDefaultButton.setBounds(430, 175, 120, 30) self.badMimesLabel = JLabel("Ignore mime types:") self.badMimesLabel.setBounds(X_BASE, 220, 200, 30) self.badMimesText = JTextArea("") self.loadBadMimes() self.badMimesText.setBounds(X_BASE, 245, 310, 30) self.badMimesButton = JButton("Save") self.badMimesButton.addActionListener(self.handleBadMimesButton) self.badMimesButton.setBounds(355, 245, 70, 30) self.badMimesDefaultButton = JButton("Load Defaults") self.badMimesDefaultButton.addActionListener( self.handleBadMimesDefaultButton) self.badMimesDefaultButton.setBounds(430, 245, 120, 30) self.otherLabel = JLabel("Other:") self.otherLabel.setBounds(40, 300, 120, 30) self.otherLabel2 = JLabel("Other:") self.otherLabel2.setBounds(X_BASE, Y_OPTION, 120, 30) self.autoSaveOption = JCheckBox("Auto save periodically") self.autoSaveOption.setSelected(True) self.autoSaveOption.addActionListener(self.handleAutoSaveOption) self.autoSaveOption.setBounds(X_BASE, Y_OPTION + Y_CHECKMARK_SPACING, 420, 30) self.repeaterOptionButton = JCheckBox( "Repeater request automatically marks as analyzed") self.repeaterOptionButton.setSelected(True) self.repeaterOptionButton.addActionListener( self.handleRepeaterOptionButton) self.repeaterOptionButton.setBounds(50, 330, 420, 30) self.scopeOptionButton = JCheckBox("Follow Burp Target In Scope rules") self.scopeOptionButton.setSelected(True) self.scopeOptionButton.addActionListener(self.handleScopeOptionButton) self.scopeOptionButton.setBounds(50, 350, 420, 30) self.startOptionButton = JCheckBox("Autostart Scope Monitor") self.startOptionButton.setSelected(True) self.startOptionButton.addActionListener(self.handleStartOption) self.startOptionButton.setBounds(50, 350 + Y_OPTION_SPACING, 420, 30) self.markTestedRequestsProxy = JCheckBox( "Color request in Proxy tab if analyzed") self.markTestedRequestsProxy.setSelected(True) self.markTestedRequestsProxy.addActionListener( self.handleTestedRequestsProxy) self.markTestedRequestsProxy.setBounds(50, 350 + Y_OPTION_SPACING * 2, 420, 30) self.markNotTestedRequestsProxy = JCheckBox( "Color request in Proxy tab if NOT analyzed") self.markNotTestedRequestsProxy.setSelected(True) self.markNotTestedRequestsProxy.addActionListener( self.handleNotTestedRequestsProxy) self.markNotTestedRequestsProxy.setBounds(50, 350 + Y_OPTION_SPACING * 3, 420, 30) self.saveButton = JButton("Save now") self.saveButton.addActionListener(self.handleSaveButton) self.saveButton.setBounds(X_BASE + 320, 95, 90, 30) self.loadButton = JButton("Load now") self.loadButton.addActionListener(self.handleLoadButton) self.loadButton.setBounds(X_BASE + 420, 95, 90, 30) self.selectPath = JButton("Select path") self.selectPath.addActionListener(self.selectExportFile) self.selectPath.setBounds(X_BASE + 530, 60, 120, 30) self.selectPathText = JTextArea("") self.selectPathText.setBounds(X_BASE, 60, 510, 30) self.selectPathLabel = JLabel("State file:") self.selectPathLabel.setBounds(X_BASE, 30, 200, 30) bGroup = ButtonGroup() bGroup.add(self.showAllButton) bGroup.add(self.showNewButton) bGroup.add(self.showTestedButton) config.add(self.clearButton) config.add(self.startButton) config.add(self.startOptionButton) config.add(self.showAllButton) config.add(self.showNewButton) config.add(self.showTestedButton) config.add(self.badExtensionsButton) config.add(self.badExtensionsText) config.add(self.badExtensionsLabel) config.add(self.badMimesButton) config.add(self.badMimesText) config.add(self.badMimesLabel) config.add(self.badExtensionsDefaultButton) config.add(self.badMimesDefaultButton) config.add(self.otherLabel) config.add(self.repeaterOptionButton) config.add(self.scopeOptionButton) config.add(self.markTestedRequestsProxy) config.add(self.markNotTestedRequestsProxy) iexport.add(self.saveButton) iexport.add(self.loadButton) iexport.add(self.selectPath) iexport.add(self.selectPathText) iexport.add(self.selectPathLabel) iexport.add(self.otherLabel2) iexport.add(self.autoSaveOption) self._config.addTab("General", config) self._config.addTab("Import/Export", iexport) ##### end config pane self._parentPane.addTab("Monitor", self._splitpane) self._parentPane.addTab("Config", self._config) # table of log entries self.logTable = Table(self) #self.logTable.setDefaultRenderer(self.logTable.getColumnClass(0), ColoredTableCellRenderer(self)) self.logTable.setAutoCreateRowSorter(True) self.logTable.setRowSelectionAllowed(True) renderer = ColoredTableCellRenderer(self) #column = TableColumn(0, 190, renderer, None) print 'Initiating... ' # this could be improved by fetching initial dimensions self.logTable.getColumn("URL").setPreferredWidth(720) # noscope self.logTable.getColumn("URL").setResizable(True) self.logTable.getColumn("Checked").setCellRenderer(renderer) self.logTable.getColumn("Checked").setPreferredWidth(80) self.logTable.getColumn("Checked").setMaxWidth(80) self.logTable.getColumn("Method").setPreferredWidth(120) #self.logTable.getColumn("Method").setMaxWidth(120) self.logTable.getColumn("Method").setResizable(True) self.logTable.getColumn("Time").setPreferredWidth(120) # noscope self.logTable.getColumn("Time").setResizable(True) scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(scrollPane) # tabs with request/response viewers tabs = JTabbedPane() self._requestViewer = callbacks.createMessageEditor(self, False) self._responseViewer = callbacks.createMessageEditor(self, False) tabs.addTab("Request", self._requestViewer.getComponent()) tabs.addTab("Response", self._responseViewer.getComponent()) self._splitpane.setRightComponent(tabs) ## Row sorter shit #self._tableRowSorterAutoProxyAutoAction = CustomTableRowSorter(self.logTable.getModel()) #self.logTable.setRowSorter(self._tableRowSorterAutoProxyAutoAction) markAnalyzedButton = JMenuItem("Mark Requests as Analyzed") markAnalyzedButton.addActionListener(markRequestsHandler(self, True)) markNotAnalyzedButton = JMenuItem("Mark Requests as NOT Analyzed") markNotAnalyzedButton.addActionListener( markRequestsHandler(self, False)) sendRequestMenu = JMenuItem("Send Request to Repeater") sendRequestMenu.addActionListener(sendRequestRepeater(self)) deleteRequestMenu = JMenuItem("Delete request") deleteRequestMenu.addActionListener(deleteRequestHandler(self)) self.menu = JPopupMenu("Popup") self.menu.add(markAnalyzedButton) self.menu.add(markNotAnalyzedButton) self.menu.add(sendRequestMenu) self.menu.add(deleteRequestMenu) # customize our UI components callbacks.customizeUiComponent(self._parentPane) callbacks.customizeUiComponent(self._splitpane) callbacks.customizeUiComponent(self._config) callbacks.customizeUiComponent(config) callbacks.customizeUiComponent(self.logTable) callbacks.customizeUiComponent(scrollPane) callbacks.customizeUiComponent(tabs) callbacks.registerContextMenuFactory(self) callbacks.registerExtensionStateListener(self) callbacks.registerScannerCheck(passiveScanner(self)) # add the custom tab to Burp's UI callbacks.addSuiteTab(self) # register ourselves as an HTTP listener callbacks.registerHttpListener(self) self.loadConfigs() print "Loaded!" print "Experimental import state.. " self.importState("") self.SC = sched.scheduler(time.time, time.sleep) self.SCC = self.SC.enter(10, 1, self.autoSave, (self.SC, )) self.SC.run() return
def __init__(self, name, iconName, tooltip, shortcut, height, app): ToggleDialog.__init__(self, name, iconName, tooltip, shortcut, height) self.app = app tools = app.tools #Main panel of the dialog mainPnl = JPanel(BorderLayout()) mainPnl.setBorder(BorderFactory.createEmptyBorder(0, 1, 1, 1)) ### First tab: errors selection and download ########################### #ComboBox with tools names self.toolsComboModel = DefaultComboBoxModel() for tool in tools: self.add_data_to_models(tool) self.toolsCombo = JComboBox(self.toolsComboModel, actionListener=ToolsComboListener(app)) renderer = ToolsComboRenderer(self.app) renderer.setPreferredSize(Dimension(20, 20)) self.toolsCombo.setRenderer(renderer) self.toolsCombo.setToolTipText( app.strings.getString("Select_a_quality_assurance_tool")) #ComboBox with categories names ("views"), of the selected tool self.viewsCombo = JComboBox(actionListener=ViewsComboListener(app)) self.viewsCombo.setToolTipText( app.strings.getString("Select_a_category_of_error")) #Popup for checks table self.checkPopup = JPopupMenu() #add favourite check self.menuItemAdd = JMenuItem( self.app.strings.getString("Add_to_favourites")) self.menuItemAdd.setIcon( ImageIcon( File.separator.join([ self.app.SCRIPTDIR, "tools", "data", "Favourites", "icons", "tool_16.png" ]))) self.menuItemAdd.addActionListener(PopupActionListener(self.app)) self.checkPopup.add(self.menuItemAdd) #remove favourite check self.menuItemRemove = JMenuItem( self.app.strings.getString("Remove_from_favourites")) self.menuItemRemove.setIcon( ImageIcon( File.separator.join([ self.app.SCRIPTDIR, "tools", "data", "Favourites", "icons", "black_tool_16.png" ]))) self.menuItemRemove.addActionListener(PopupActionListener(self.app)) self.checkPopup.add(self.menuItemRemove) #Help link for selected check self.menuItemHelp = JMenuItem(self.app.strings.getString("check_help")) self.menuItemHelp.setIcon( ImageIcon( File.separator.join( [self.app.SCRIPTDIR, "images", "icons", "info_16.png"]))) self.checkPopup.add(self.menuItemHelp) self.menuItemHelp.addActionListener(PopupActionListener(self.app)) #Table with checks of selected tool and view self.checksTable = JTable() self.iconrenderer = IconRenderer() self.iconrenderer.setHorizontalAlignment(JLabel.CENTER) scrollPane = JScrollPane(self.checksTable) self.checksTable.setFillsViewportHeight(True) tableSelectionModel = self.checksTable.getSelectionModel() tableSelectionModel.addListSelectionListener(ChecksTableListener(app)) self.checksTable.addMouseListener( ChecksTableClickListener(app, self.checkPopup, self.checksTable)) #Favourite area status indicator self.favAreaIndicator = JLabel() self.update_favourite_zone_indicator() self.favAreaIndicator.addMouseListener(FavAreaIndicatorListener(app)) #label with OSM id of the object currently edited and number of #errors still to review self.checksTextFld = JTextField("", editable=0, border=None, background=None) #checks buttons btnsIconsDir = File.separator.join([app.SCRIPTDIR, "images", "icons"]) downloadIcon = ImageIcon( File.separator.join([btnsIconsDir, "download.png"])) self.downloadBtn = JButton(downloadIcon, actionPerformed=app.on_downloadBtn_clicked, enabled=0) startIcon = ImageIcon( File.separator.join([btnsIconsDir, "start_fixing.png"])) self.startBtn = JButton(startIcon, actionPerformed=app.on_startBtn_clicked, enabled=0) self.downloadBtn.setToolTipText( app.strings.getString("Download_errors_in_this_area")) self.startBtn.setToolTipText( app.strings.getString("Start_fixing_the_selected_errors")) #tab layout panel1 = JPanel(BorderLayout(0, 1)) comboboxesPnl = JPanel(GridLayout(0, 2, 5, 0)) comboboxesPnl.add(self.toolsCombo) comboboxesPnl.add(self.viewsCombo) checksPnl = JPanel(BorderLayout(0, 1)) checksPnl.add(scrollPane, BorderLayout.CENTER) self.statsPanel = JPanel(BorderLayout(4, 0)) self.statsPanel_def_color = self.statsPanel.getBackground() self.statsPanel.add(self.checksTextFld, BorderLayout.CENTER) self.statsPanel.add(self.favAreaIndicator, BorderLayout.LINE_START) checksPnl.add(self.statsPanel, BorderLayout.PAGE_END) checksButtonsPnl = JPanel(GridLayout(0, 2, 0, 0)) checksButtonsPnl.add(self.downloadBtn) checksButtonsPnl.add(self.startBtn) panel1.add(comboboxesPnl, BorderLayout.PAGE_START) panel1.add(checksPnl, BorderLayout.CENTER) panel1.add(checksButtonsPnl, BorderLayout.PAGE_END) ### Second tab: errors fixing ########################################## #label with error stats self.errorTextFld = JTextField("", editable=0, border=None, background=None) #label with current error description self.errorDesc = JLabel("") self.errorDesc.setAlignmentX(0.5) #error buttons errorInfoBtnIcon = ImageProvider.get("info") self.errorInfoBtn = JButton( errorInfoBtnIcon, actionPerformed=app.on_errorInfoBtn_clicked, enabled=0) notErrorIcon = ImageIcon( File.separator.join([btnsIconsDir, "not_error.png"])) self.notErrorBtn = JButton( notErrorIcon, actionPerformed=app.on_falsePositiveBtn_clicked, enabled=0) ignoreIcon = ImageIcon(File.separator.join([btnsIconsDir, "skip.png"])) self.ignoreBtn = JButton(ignoreIcon, actionPerformed=app.on_ignoreBtn_clicked, enabled=0) correctedIcon = ImageIcon( File.separator.join([btnsIconsDir, "corrected.png"])) self.correctedBtn = JButton( correctedIcon, actionPerformed=app.on_correctedBtn_clicked, enabled=0) nextIcon = ImageIcon(File.separator.join([btnsIconsDir, "next.png"])) self.nextBtn = JButton(nextIcon, actionPerformed=app.on_nextBtn_clicked, enabled=0) #self.nextBtn.setMnemonic(KeyEvent.VK_RIGHT) self.errorInfoBtn.setToolTipText( app.strings.getString("open_error_info_dialog")) self.notErrorBtn.setToolTipText( app.strings.getString("flag_false_positive")) self.ignoreBtn.setToolTipText( app.strings.getString("Skip_and_don't_show_me_this_error_again")) self.correctedBtn.setToolTipText( app.strings.getString("flag_corrected_error")) self.nextBtn.setToolTipText(app.strings.getString("Go_to_next_error")) #tab layout self.panel2 = JPanel(BorderLayout()) self.panel2.add(self.errorTextFld, BorderLayout.PAGE_START) self.panel2.add(self.errorDesc, BorderLayout.CENTER) errorButtonsPanel = JPanel(GridLayout(0, 5, 0, 0)) errorButtonsPanel.add(self.errorInfoBtn) errorButtonsPanel.add(self.notErrorBtn) errorButtonsPanel.add(self.ignoreBtn) errorButtonsPanel.add(self.correctedBtn) errorButtonsPanel.add(self.nextBtn) self.panel2.add(errorButtonsPanel, BorderLayout.PAGE_END) #Layout self.tabbedPane = JTabbedPane() self.tabbedPane.addTab(self.app.strings.getString("Download"), None, panel1, self.app.strings.getString("download_tab")) mainPnl.add(self.tabbedPane, BorderLayout.CENTER) self.createLayout(mainPnl, False, None)
class View: def __init__(self, issues): self.json = issues.get_json() self.issues_object = issues self.issues = issues.get_issues() self.scanner_issues = issues.get_scanner_issues() self.scanner_panes = {} self.scanner_tables = {} self.is_scanner_panes = [] self.set_vuln_tree() self.set_tree() self.set_scanner_panes() self.set_pane() self.set_tsl() def set_callbacks(self, callbacks): self.callbacks = callbacks def set_helpers(self, helpers): self.helpers = helpers def get_helpers(self): return self.helpers def get_issues(self): return self.issues def get_scanner_issues(self): return self.scanner_issues def set_scanner_count(self, is_checked, issue_name, issue_param): self.issues_object.set_scanner_count(self, is_checked, issue_name, issue_param) def set_is_scanner_pane(self, scanner_pane): self.is_scanner_panes.append(scanner_pane) def get_is_scanner_pane(self, scanner_pane): for pane in self.get_is_scanner_panes(): if pane == scanner_pane: return True return False def get_is_scanner_panes(self): return self.is_scanner_panes def set_vuln_tree(self): self.vuln_tree = DefaultMutableTreeNode("Vulnerability Classes") vulns = self.json["issues"] # TODO: Sort the functionality by name and by vuln class for vuln_name in vulns: vuln = DefaultMutableTreeNode(vuln_name) self.vuln_tree.add(vuln) parameters = self.json["issues"][vuln_name]["params"] for parameter in parameters: param_node = DefaultMutableTreeNode(parameter) vuln.add(param_node) # Creates a JTree object from the checklist def set_tree(self): self.tree = JTree(self.vuln_tree) self.tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION ) def get_tree(self): return self.tree # Creates the tabs dynamically using data from the JSON file def set_scanner_panes(self): issues = self.issues for issue in issues: issue_name = issue["name"] issue_param = issue["param"] key = issue_name + "." + issue_param top_pane = self.create_request_list_pane(issue_name) bottom_pane = self.create_tabbed_pane() scanner_pane = JSplitPane(JSplitPane.VERTICAL_SPLIT, top_pane, bottom_pane) self.scanner_panes[key] = scanner_pane def get_scanner_panes(self): return self.scanner_panes def create_request_list_pane(self, issue_name): request_list_pane = JScrollPane() return request_list_pane # Creates a JTabbedPane for each vulnerability per functionality def create_tabbed_pane(self): tabbed_pane = JTabbedPane() tabbed_pane.add("Advisory", JScrollPane()) tabbed_pane.add("Request", JScrollPane()) tabbed_pane.add("Response", JScrollPane()) self.tabbed_pane = tabbed_pane return tabbed_pane def set_tsl(self): tsl = TSL(self) self.tree.addTreeSelectionListener(tsl) return def set_pane(self): status = JTextArea() status.setLineWrap(True) status.setText("Nothing selected") self.status = status request_list_pane = JScrollPane() scanner_pane = JSplitPane(JSplitPane.VERTICAL_SPLIT, request_list_pane, self.tabbed_pane ) self.pane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT, JScrollPane(self.tree), scanner_pane ) self.pane.setDividerLocation(310) self.pane.getLeftComponent().setMinimumSize(Dimension(310, 300)) def get_pane(self): return self.pane def set_scanner_table(self, scanner_pane, scanner_table): self.scanner_tables[scanner_pane] = scanner_table def get_scanner_table(self, scanner_pane): return self.scanner_tables[scanner_pane] def set_scanner_pane(self, scanner_pane): request_table_pane = scanner_pane.getTopComponent() scanner_table = self.get_scanner_table(scanner_pane) request_table_pane.getViewport().setView(scanner_table) request_table_pane.revalidate() request_table_pane.repaint() def create_scanner_pane(self, scanner_pane, issue_name, issue_param): scanner_issues = self.get_scanner_issues() request_table_pane = scanner_pane.getTopComponent() scanner_table_model = ScannerTableModel() scanner_table_model.addColumn("Checked") scanner_table_model.addColumn("Host") scanner_table_model.addColumn("Path") # Search all issues for the correct issue. Once found, add it into # the scanner table model to be showed in the UI. for scanner_issue in scanner_issues: is_same_name = scanner_issue.getIssueName() == issue_name is_same_param = scanner_issue.getParameter() == issue_param is_same_issue = is_same_name and is_same_param if is_same_issue: scanner_table_model.addRow([ False, scanner_issue.getHttpService().getHost(), scanner_issue.getUrl() ]) scanner_table = JTable(scanner_table_model) scanner_table.getColumnModel().getColumn(0).setCellEditor(DefaultCellEditor(JCheckBox())) scanner_table.putClientProperty("terminateEditOnFocusLost", True) scanner_table_listener = ScannerTableListener(self, scanner_table, issue_name, issue_param) scanner_table_model.addTableModelListener(scanner_table_listener) scanner_table_list_listener = IssueListener(self, scanner_table, scanner_pane, issue_name, issue_param) scanner_table.getSelectionModel().addListSelectionListener(scanner_table_list_listener) self.set_scanner_table(scanner_pane, scanner_table) request_table_pane.getViewport().setView(scanner_table) request_table_pane.revalidate() request_table_pane.repaint() def set_tabbed_pane(self, scanner_pane, request_list, issue_url, issue_name, issue_param): tabbed_pane = scanner_pane.getBottomComponent() scanner_issues = self.get_scanner_issues() for scanner_issue in scanner_issues: is_same_url = scanner_issue.getUrl() == issue_url is_same_name = scanner_issue.getIssueName() == issue_name is_same_param = scanner_issue.getParameter() == issue_param is_same_issue = is_same_url and is_same_name and is_same_param if is_same_issue: current_issue = scanner_issue self.set_context_menu(request_list, scanner_issue) break advisory_tab_pane = self.set_advisory_tab_pane(current_issue) tabbed_pane.setComponentAt(0, advisory_tab_pane) request_tab_pane = self.set_request_tab_pane(current_issue) tabbed_pane.setComponentAt(1, request_tab_pane) response_tab_pane = self.set_response_tab_pane(current_issue) tabbed_pane.setComponentAt(2, response_tab_pane) def set_advisory_tab_pane(self, scanner_issue): advisory_pane = JEditorPane() advisory_pane.setEditable(False) advisory_pane.setEnabled(True) advisory_pane.setContentType("text/html") link_listener = LinkListener() advisory_pane.addHyperlinkListener(link_listener) advisory_pane.setText("<html>" + "<b>Location</b>: " + scanner_issue.getUrl() + "<br><br>" + scanner_issue.getIssueDetail() + "</html>" ) # Set a context menu self.set_context_menu(advisory_pane, scanner_issue) return JScrollPane(advisory_pane) def set_request_tab_pane(self, scanner_issue): raw_request = scanner_issue.getRequestResponse().getRequest() request_body = StringUtil.fromBytes(raw_request) request_body = request_body.encode("utf-8") request_tab_textarea = JTextArea(request_body) request_tab_textarea.setLineWrap(True) # Set a context menu self.set_context_menu(request_tab_textarea, scanner_issue) return JScrollPane(request_tab_textarea) def set_response_tab_pane(self, scanner_issue): raw_response = scanner_issue.getRequestResponse().getResponse() response_body = StringUtil.fromBytes(raw_response) response_body = response_body.encode("utf-8") response_tab_textarea = JTextArea(response_body) response_tab_textarea.setLineWrap(True) # Set a context menu self.set_context_menu(response_tab_textarea, scanner_issue) return JScrollPane(response_tab_textarea) # Pass scanner_issue as argument def set_context_menu(self, component, scanner_issue): self.context_menu = JPopupMenu() repeater = JMenuItem("Send to Repeater") repeater.addActionListener(PopupListener(scanner_issue, self.callbacks)) intruder = JMenuItem("Send to Intruder") intruder.addActionListener(PopupListener(scanner_issue, self.callbacks)) hunt = JMenuItem("Send to HUNT") self.context_menu.add(repeater) self.context_menu.add(intruder) context_menu_listener = ContextMenuListener(component, self.context_menu) component.addMouseListener(context_menu_listener) def get_context_menu(self): return self.context_menu
def registerExtenderCallbacks(self, callbacks): self._panel = JPanel() self._panel.setLayout(BorderLayout()) #self._panel.setSize(400,400) # sourrounding try\except because Burp is not giving enough info try: # creating all the UI elements # create the split pane self._split_pane_horizontal = JSplitPane( JSplitPane.HORIZONTAL_SPLIT) self._split_panel_vertical = JSplitPane(JSplitPane.VERTICAL_SPLIT) # create panels self._panel_top = JPanel() self._panel_top.setLayout(BorderLayout()) self._panel_bottom = JPanel() self._panel_bottom.setLayout(BorderLayout()) self._panel_right = JPanel() self._panel_right.setLayout(BorderLayout()) self._panel_request = JPanel() self._panel_request.setLayout(BorderLayout()) self._panel_response = JPanel() self._panel_response.setLayout(BorderLayout()) # create the tabbed pane used to show request\response self._tabbed_pane = JTabbedPane(JTabbedPane.TOP) # create the tabbed pane used to show aslan++\concretization file self._tabbed_pane_editor = JTabbedPane(JTabbedPane.TOP) # create the bottom command for selecting the SQL file and # generating the model self._button_generate = JButton( 'Generate!', actionPerformed=self._generate_model) self._button_save = JButton('Save', actionPerformed=self._save_model) self._button_select_sql = JButton( 'Select SQL', actionPerformed=self._select_sql_file) self._text_field_sql_file = JTextField(20) self._panel_bottom_commands = JPanel() layout = GroupLayout(self._panel_bottom_commands) layout.setAutoCreateGaps(True) layout.setAutoCreateContainerGaps(True) seq_layout = layout.createSequentialGroup() seq_layout.addComponent(self._text_field_sql_file) seq_layout.addComponent(self._button_select_sql) seq_layout.addComponent(self._button_generate) seq_layout.addComponent(self._button_save) layout.setHorizontalGroup(seq_layout) # create the message editors that will be used to show request and response self._message_editor_request = callbacks.createMessageEditor( None, True) self._message_editor_response = callbacks.createMessageEditor( None, True) # create the table that will be used to show the messages selected for # the translation self._columns_names = ('Host', 'Method', 'URL') dataModel = NonEditableModel(self._table_data, self._columns_names) self._table = JTable(dataModel) self._scrollPane = JScrollPane() self._scrollPane.getViewport().setView((self._table)) popmenu = JPopupMenu() delete_item = JMenuItem("Delete") delete_item.addActionListener(self) popmenu.add(delete_item) self._table.setComponentPopupMenu(popmenu) self._table.addMouseListener(self) # add all the elements self._panel_request.add( self._message_editor_request.getComponent()) self._panel_response.add( self._message_editor_response.getComponent()) self._tabbed_pane.addTab("Request", self._panel_request) self._tabbed_pane.addTab("Response", self._panel_response) self._panel_top.add(self._scrollPane, BorderLayout.CENTER) self._panel_bottom.add(self._tabbed_pane, BorderLayout.CENTER) scroll = JScrollPane(self._panel_bottom) self._panel_right.add(self._tabbed_pane_editor, BorderLayout.CENTER) self._panel_right.add(self._panel_bottom_commands, BorderLayout.PAGE_END) self._split_panel_vertical.setTopComponent(self._panel_top) self._split_panel_vertical.setBottomComponent(scroll) self._split_pane_horizontal.setLeftComponent( self._split_panel_vertical) self._split_pane_horizontal.setRightComponent(self._panel_right) self._panel.addComponentListener(self) self._panel.add(self._split_pane_horizontal) self._callbacks = callbacks callbacks.setExtensionName("WAFEx") callbacks.addSuiteTab(self) callbacks.registerContextMenuFactory(self) except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno)
class DataPanel(JPanel,MouseListener): def __init__(self,view): JPanel.__init__(self) self.view=view self.background=Color.white self.layout=BorderLayout() self.popup=JPopupMenu() self.popup_items={} self.add(self.make_controls(),BorderLayout.SOUTH) data,title=self.extract_data() self.table=JTable(DefaultTableModel(data,title)) scroll=JScrollPane(self.table) self.add(scroll) scroll.addMouseListener(self) self.table.tableHeader.addMouseListener(self) self.table.addMouseListener(self) self.fileChooser=JFileChooser() self.fileChooser.setFileFilter(CSVFilter()) self.fileChooser.setSelectedFile(File('%s.csv'%self.view.network.name)) def make_controls(self): from timeview.components.timecontrol import Icon, ShadedIcon panel=JPanel(background=self.background) panel.add(JButton(Icon.refresh,actionPerformed=self.refresh,rolloverIcon=ShadedIcon.refresh,toolTipText='refresh',borderPainted=False,focusPainted=False,contentAreaFilled=False)) filter=JPanel(layout=BorderLayout(),opaque=False) self.filter = JSpinner(SpinnerNumberModel(self.view.tau_filter,0,0.5,0.01),stateChanged=self.refresh) filter.add(self.filter) filter.add(JLabel('filter'),BorderLayout.NORTH) filter.maximumSize=filter.preferredSize panel.add(filter) decimals=JPanel(layout=BorderLayout(),opaque=False) self.decimals = JSpinner(SpinnerNumberModel(3,0,10,1),stateChanged=self.refresh) decimals.add(self.decimals) decimals.add(JLabel('decimal places'),BorderLayout.NORTH) decimals.maximumSize=decimals.preferredSize panel.add(decimals) panel.add(JButton(Icon.save,actionPerformed=self.save,rolloverIcon=ShadedIcon.save,toolTipText='save',borderPainted=False,focusPainted=False,contentAreaFilled=False)) return panel def extract_data(self): pause_state=self.view.paused self.view.paused=True while self.view.simulating: java.lang.Thread.sleep(10) tau=float(self.filter.value) dt=self.view.dt if tau<dt: dt_tau=None else: dt_tau=dt/tau decimals=int(self.decimals.value) format='%%1.%df'%decimals start_index=max(0,self.view.timelog.tick_count-self.view.timelog.tick_limit+1) count=min(self.view.timelog.tick_limit,self.view.timelog.tick_count) start_time=start_index*self.view.dt data=None title=['t'] keys = self.view.watcher.active.keys() keys.sort() for key in keys: watch = self.view.watcher.active[key] name,func,args=key code='%s.%s%s'%(name,func.__name__,args) if code not in self.popup_items: state=True if 'spike' in func.__name__: state=False if 'voltage' in func.__name__: state=False self.popup_items[code]=JCheckBoxMenuItem(code,state,stateChanged=self.refresh) self.popup.add(self.popup_items[code]) if self.popup_items[code].state is False: continue d=watch.get(dt_tau=dt_tau,start=start_index,count=count) n=len(watch.get_first()) if data is None: data=[] while len(data)<len(d): data.append(['%0.4f'%(start_time+(len(data)+0)*self.view.dt)]) for i in range(n): title.append('%s[%d]'%(code,i)) for j in range(len(data)): dd=d[j] if dd is None: data[j].append('') else: data[j].append(format%dd[i]) self.view.paused=pause_state return data,title def save(self,event=None): if self.fileChooser.showSaveDialog(self)==JFileChooser.APPROVE_OPTION: f=self.fileChooser.getSelectedFile() writer=BufferedWriter(FileWriter(f)) data,title=self.extract_data() title=[t.replace(',',' ') for t in title] writer.write(','.join(title)+'\n') for row in data: writer.write(','.join(row)+'\n') writer.close() def refresh(self,event=None): data,title=self.extract_data() self.table.model.setDataVector(data,title) def mouseClicked(self, event): if event.button==MouseEvent.BUTTON3 or (event.button==MouseEvent.BUTTON1 and event.isControlDown()): if self.popup is not None: self.popup.show(event.source,event.x-5,event.y-5) def mouseEntered(self, event): pass def mouseExited(self, event): pass def mousePressed(self, event): pass def mouseReleased(self, event): pass
class PropertyEditor(WindowAdapter): """ Edits Tabular Properties of a given WindowAdapter """ instances = {} last_location = None locations = {} last_size = None sizes = {} NEW_WINDOW_OFFSET = 32 offset = NEW_WINDOW_OFFSET @staticmethod def get_instance(text="Property Editor", columns=None, data=None, empty=None, add_actions=True, actions=None): """ Singleton Method based on the text property. It tries to generate only one property configuration page per text. :param text: getinstance key :param columns: proparty columns it should be an array alike :param data: it contains the current property rows :param empty: empty row property when adding a new one :param add_actions: include or not new actions :param actions: default set of actions to be appended to Add and Delete Rows :return: a new instance of PropertyEditor or a reused one. """ if not actions: actions = [] if not columns: columns = [] if data == None: data = [] if not empty: empty = [] try: PropertyEditor.instances[text] except KeyError: PropertyEditor.instances[text] = \ PropertyEditor().__private_init__(text, columns, data, empty, add_actions, actions) try: PropertyEditor.instances[text].this.setLocation( PropertyEditor.locations[text]) except KeyError: if PropertyEditor.last_location: PropertyEditor.instances[text].this.setLocation( PropertyEditor.last_location.x + PropertyEditor.offset, PropertyEditor.last_location.y + PropertyEditor.offset) PropertyEditor.offset = PropertyEditor.NEW_WINDOW_OFFSET try: PropertyEditor.instances[text].this.setSize( PropertyEditor.sizes[text]) except KeyError: if PropertyEditor.last_size: PropertyEditor.instances[text].this.setSize( PropertyEditor.last_size) PropertyEditor.last_location = PropertyEditor.instances[ text].this.getLocation() PropertyEditor.last_size = PropertyEditor.instances[ text].this.getSize() ## Hack ON: Bring on Front PropertyEditor.instances[text].this.setAlwaysOnTop(True) PropertyEditor.instances[text].this.setAlwaysOnTop(False) ## Hack OFF return PropertyEditor.instances[text] def __private_init__(self, text="Property Editor", columns=None, data=None, empty=None, add_actions=True, actions=None): if not actions: actions = [] if not columns: columns = [] if data == None: data = [] if not empty: empty = [] self._text = text self.this = JFrame(text) self._table = JTable() self._dtm = DefaultTableModel(0, 0) self._dtm.setColumnIdentifiers(columns) self._table.setModel(self._dtm) self._data = data for d in data: self._dtm.addRow(d) self._pane = JScrollPane(self._table) self.this.add(self._pane) self._empty = empty self.this.addWindowListener(self) self._dtm.addTableModelListener(lambda _: self._update_model()) self.this.setLocation(PropertyEditor.NEW_WINDOW_OFFSET, PropertyEditor.NEW_WINDOW_OFFSET) if add_actions: self._popup = JPopupMenu() self._pane.setComponentPopupMenu(self._popup) inherits_popup_menu(self._pane) self._actions = actions self._actions.append( ExecutorAction('Remove Selected Rows', action=lambda e: self._remove_row())) self._actions.append( ExecutorAction('Add New Row', action=lambda e: self._add_row())) for action in self._actions: self._popup.add(action.menuitem) self.this.setForeground(Color.black) self.this.setBackground(Color.lightGray) self.this.pack() self.this.setVisible(True) self.this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE) return self def _add_row(self): """ Add a new row the selection :return: None """ self._dtm.addRow(self._empty) def _remove_row(self): """ Remove all the selected rows from the selection :return: """ rows = self._table.getSelectedRows() for i in range(0, len(rows)): self._dtm.removeRow(rows[i] - i) def windowClosing(self, evt): """ Overrides WindowAdapter method :param evt: unused :return: None """ PropertyEditor.locations[self._text] = self.this.getLocation() PropertyEditor.sizes[self._text] = self.this.getSize() PropertyEditor.last_location = self.this.getLocation() PropertyEditor.last_size = self.this.getSize() PropertyEditor.offset = 0 self.this.setVisible(False) self.this.dispose() del PropertyEditor.instances[self._text] def _update_model(self): """ Update the data content with the updated rows :return: None """ del self._data[:] nRow = self._dtm.getRowCount() nCol = self._dtm.getColumnCount() for i in range(0, nRow): self._data.append([None] * nCol) for j in range(0, nCol): d = str(self._dtm.getValueAt(i, j)).lower() if d == 'none' or d == '': self._data[i][j] = None elif d == 'true' or d == 't': self._data[i][j] = True elif d == 'false' or d == 'f': self._data[i][j] = False else: try: self._data[i][j] = int(self._dtm.getValueAt(i, j)) except ValueError: self._data[i][j] = self._dtm.getValueAt(i, j)
def initTabs(self): # ## init autorize tabs # self.logTable = Table(self) self.logTable.setAutoCreateRowSorter(True) tableWidth = self.logTable.getPreferredSize().width self.logTable.getColumn("ID").setPreferredWidth( Math.round(tableWidth / 50 * 2)) self.logTable.getColumn("URL").setPreferredWidth( Math.round(tableWidth / 50 * 24)) self.logTable.getColumn("Orig. Length").setPreferredWidth( Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Modif. Length").setPreferredWidth( Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Unauth. Length").setPreferredWidth( Math.round(tableWidth / 50 * 4)) self.logTable.getColumn( "Authorization Enforcement Status").setPreferredWidth( Math.round(tableWidth / 50 * 4)) self.logTable.getColumn( "Authorization Unauth. Status").setPreferredWidth( Math.round(tableWidth / 50 * 4)) self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._splitpane.setResizeWeight(1) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) self.scrollPane.getVerticalScrollBar().addAdjustmentListener( autoScrollListener(self)) self.menuES0 = JCheckBoxMenuItem(self._enfocementStatuses[0], True) self.menuES1 = JCheckBoxMenuItem(self._enfocementStatuses[1], True) self.menuES2 = JCheckBoxMenuItem(self._enfocementStatuses[2], True) self.menuES0.addItemListener(menuTableFilter(self)) self.menuES1.addItemListener(menuTableFilter(self)) self.menuES2.addItemListener(menuTableFilter(self)) copyURLitem = JMenuItem("Copy URL") copyURLitem.addActionListener(copySelectedURL(self)) self.menu = JPopupMenu("Popup") self.menu.add(copyURLitem) self.menu.add(self.menuES0) self.menu.add(self.menuES1) self.menu.add(self.menuES2) self.tabs = JTabbedPane() self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self._originalrequestViewer = self._callbacks.createMessageEditor( self, False) self._originalresponseViewer = self._callbacks.createMessageEditor( self, False) self._unauthorizedrequestViewer = self._callbacks.createMessageEditor( self, False) self._unauthorizedresponseViewer = self._callbacks.createMessageEditor( self, False) self.tabs.addTab("Modified Request", self._requestViewer.getComponent()) self.tabs.addTab("Modified Response", self._responseViewer.getComponent()) self.tabs.addTab("Original Request", self._originalrequestViewer.getComponent()) self.tabs.addTab("Original Response", self._originalresponseViewer.getComponent()) self.tabs.addTab("Unauthenticated Request", self._unauthorizedrequestViewer.getComponent()) self.tabs.addTab("Unauthenticated Response", self._unauthorizedresponseViewer.getComponent()) self.tabs.addTab("Configuration", self.pnl) self.tabs.setSelectedIndex(6) self._splitpane.setRightComponent(self.tabs)