def createMainWindow(): # Create window frame = JFrame('Epiphany Core Visualisation', defaultCloseOperation=JFrame.EXIT_ON_CLOSE, size=(660, 675)) # Main layout mainLayout = JPanel() frame.add(mainLayout) # Title #title = JLabel('hello', JLabel.CENTER) #mainLayout.add(title) # Cores corepanel = JPanel(GridLayout(8, 8)) global cores cores = [] for i in range(0, 64): core = JPanel(GridLayout(2, 1)) core.setPreferredSize(Dimension(80, 80)) corename = '(' + str(i % 8) + ',' + str(i / 8) + ')' namelabel = JLabel(corename, JLabel.CENTER) namelabel.setFont(Font("Dialog", Font.PLAIN, 18)) portname = str(i + MINPORT) portlabel = JLabel(portname, JLabel.CENTER) portlabel.setFont(Font("Dialog", Font.PLAIN, 16)) core.add(namelabel) core.add(portlabel) core.setBackground(Color.BLACK) corepanel.add(core) cores.append(core) mainLayout.add(corepanel) frame.visible = True
def helpMenu(self,event): self._helpPopup = JFrame('JWT Fuzzer', size=(550, 450) ); self._helpPopup.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) helpPanel = JPanel() helpPanel.setPreferredSize(Dimension(550, 450)) helpPanel.setBorder(EmptyBorder(10, 10, 10, 10)) helpPanel.setLayout(BoxLayout(helpPanel, BoxLayout.Y_AXIS)) self._helpPopup.setContentPane(helpPanel) helpHeadingText = JLabel("<html><h2>JWT Fuzzer</h2></html>") authorText = JLabel("<html><p>@author: <pinnace></p></html>") aboutText = JLabel("<html><br /> <p>This extension adds an Intruder payload processor for JWTs.</p><br /></html>") repositoryText = JLabel("<html>Documentation and source code:</html>") repositoryLink = JLabel("<html>- <a href=\"https://github.com/pinnace/burp-jwt-fuzzhelper-extension\">https://github.com/pinnace/burp-jwt-fuzzhelper-extension</a></html>") licenseText = JLabel("<html><br/><p>JWT Fuzzer uses a GPL 3 license. This license does not apply to the dependency below:<p></html>") dependencyLink = JLabel("<html>- <a href=\"https://github.com/jpadilla/pyjwt/blob/master/LICENSE\">pyjwt</a></html>") dependencyLink.addMouseListener(ClickListener()) dependencyLink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)) repositoryLink.addMouseListener(ClickListener()) repositoryLink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)) helpPanel.add(helpHeadingText) helpPanel.add(authorText) helpPanel.add(aboutText) helpPanel.add(repositoryText) helpPanel.add(repositoryLink) helpPanel.add(licenseText) helpPanel.add(dependencyLink) self._helpPopup.setSize(Dimension(550, 450)) self._helpPopup.pack() self._helpPopup.setLocationRelativeTo(None) self._helpPopup.setVisible(True) return
def createButtonPane(self): """Create a new button pane for the message editor tab""" self._button_listener = EditorButtonListener(self) panel = JPanel() panel.setLayout(BoxLayout(panel, BoxLayout.Y_AXIS)) panel.setBorder(EmptyBorder(5, 5, 5, 5)) panel.add(Box.createRigidArea(Dimension(0, 5))) type_scroll_pane = JScrollPane(self._type_list_component) type_scroll_pane.setMaximumSize(Dimension(200, 100)) type_scroll_pane.setMinimumSize(Dimension(150, 100)) panel.add(type_scroll_pane) panel.add(Box.createRigidArea(Dimension(0, 3))) new_type_panel = JPanel() new_type_panel.setLayout(BoxLayout(new_type_panel, BoxLayout.X_AXIS)) new_type_panel.add(self._new_type_field) new_type_panel.add(Box.createRigidArea(Dimension(3, 0))) new_type_panel.add( self.createButton( "New", "new-type", "Save this message's type under a new name" ) ) new_type_panel.setMaximumSize(Dimension(200, 20)) new_type_panel.setMinimumSize(Dimension(150, 20)) panel.add(new_type_panel) button_panel = JPanel() button_panel.setLayout(FlowLayout()) if self._editable: button_panel.add( self.createButton( "Validate", "validate", "Validate the message can be encoded." ) ) button_panel.add( self.createButton("Edit Type", "edit-type", "Edit the message type") ) button_panel.add( self.createButton( "Reset Message", "reset", "Reset the message and undo changes" ) ) button_panel.add( self.createButton( "Clear Type", "clear-type", "Reparse the message with an empty type" ) ) button_panel.setMinimumSize(Dimension(100, 200)) button_panel.setPreferredSize(Dimension(200, 1000)) panel.add(button_panel) return panel
def createMainWindow(): # Create window frame = JFrame('Epiphany Core Visualisation', defaultCloseOperation = JFrame.EXIT_ON_CLOSE, size = (660,675) ) # Main layout mainLayout = JPanel() frame.add(mainLayout) # Title #title = JLabel('hello', JLabel.CENTER) #mainLayout.add(title) # Cores corepanel = JPanel(GridLayout(8,8)) global cores cores = [] for i in range(0,64): core = JPanel(GridLayout(2,1)) core.setPreferredSize(Dimension(80,80)) corename = '(' + str(i%8) + ',' + str(i/8) + ')' namelabel = JLabel(corename, JLabel.CENTER) namelabel.setFont(Font("Dialog", Font.PLAIN, 18)) portname = str(i+MINPORT) portlabel = JLabel(portname, JLabel.CENTER) portlabel.setFont(Font("Dialog", Font.PLAIN, 16)) core.add(namelabel) core.add(portlabel) core.setBackground(Color.BLACK) corepanel.add(core) cores.append(core) mainLayout.add(corepanel) frame.visible = True
def build_panels(self, the_dialog): self.menu_panel = JPanel() self.menu_panel.setLayout(BoxLayout(self.menu_panel, BoxLayout.Y_AXIS)) self.menu_panel.setPreferredSize(Dimension(200, 200)) the_dialog.add(self.menu_panel, BorderLayout.LINE_START) config_panel = JPanel() config_panel.setPreferredSize(Dimension(500, 600)) config_panel.setLayout(BoxLayout(config_panel, BoxLayout.Y_AXIS)) the_dialog.add(config_panel, BorderLayout.CENTER) # Profile properties profile_props_panel = config_dialog.ProfilePropsConfig() profile_props_menu_item = ui_components.MenuItem( "Profile Properties", profile_props_panel) profile_props_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(profile_props_menu_item) config_panel.add(profile_props_panel) # Filters filters_panel = config_dialog.FiltersConfig() filters_menu_item = ui_components.MenuItem("Filters", filters_panel) filters_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(filters_menu_item) config_panel.add(filters_panel) # Rate control rate_panel = config_dialog.RateConfig() rate_menu_item = ui_components.MenuItem("Rate", rate_panel) rate_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(rate_menu_item) config_panel.add(rate_panel) # Delay control delay_panel = config_dialog.DelayConfig() delay_menu_item = ui_components.MenuItem("Delay", delay_panel) delay_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(delay_menu_item) config_panel.add(delay_panel) # Loss control loss_panel = config_dialog.LossConfig() loss_menu_item = ui_components.MenuItem("Loss", loss_panel) loss_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(loss_menu_item) config_panel.add(loss_panel) # Corruption control corrupt_panel = config_dialog.CorruptConfig() corrupt_menu_item = ui_components.MenuItem("Corrupt", corrupt_panel) corrupt_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(corrupt_menu_item) config_panel.add(corrupt_panel) # Duplication control duplicate_panel = config_dialog.DuplicateConfig() duplicate_menu_item = ui_components.MenuItem("Duplicate", duplicate_panel) duplicate_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(duplicate_menu_item) config_panel.add(duplicate_panel) # Reorder control reorder_panel = config_dialog.ReorderConfig() reorder_menu_item = ui_components.MenuItem("Reorder", reorder_panel) reorder_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(reorder_menu_item) config_panel.add(reorder_panel) # Default selection profile_props_panel.set_selected(True)
class MainFrame(JFrame): menu_panel = None profile_table = None profile_table_model = None def __init__(self): super(MainFrame, self).__init__() self.init_ui() def init_ui(self): self.setTitle("QDisc Edit Profile") self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) self.setLocation(250, 100) self.setSize(1024, 400) # self.setExtendedState(JFrame.MAXIMIZED_BOTH) main_panel = JPanel() main_panel.setLayout(BorderLayout()) self.setContentPane(main_panel) # Build the config dialog first, so it can be attached to the Edit button config_dialog = JPanel() config_dialog.setLayout(BorderLayout()) self.build_panels(config_dialog) def show_config_dialog(event): result = JOptionPane.showConfirmDialog( self, config_dialog, "Edit Profile", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE) if result == 0: print "Will save results" top_panel = JPanel() top_panel.setLayout(FlowLayout(FlowLayout.LEADING)) title_lbl = JLabel("TODO Set title") title_lbl.setFont(ui_components.get_title_font(title_lbl)) top_panel.add(title_lbl) main_panel.add(top_panel, BorderLayout.PAGE_START) self.profile_table = self.initProfilesTable() scrollPane = JScrollPane(self.profile_table) main_panel.add(scrollPane, BorderLayout.CENTER) # self.profile_list.setCellRenderer(ui_components.FilterRenderer()) buttons_panel = JPanel() buttons_panel.setLayout(FlowLayout(FlowLayout.LEADING)) main_panel.add(buttons_panel, BorderLayout.PAGE_END) edit_profile_btn = JButton("Edit", actionPerformed=show_config_dialog) buttons_panel.add(edit_profile_btn) # status_panel = self.build_status_panel(b) # main_panel.add(status_panel, BorderLayout.PAGE_END) self.setVisible(True) # For the config dialog def show_panel(self, menu_item): for component in self.menu_panel.getComponents(): if isinstance(component, ui_components.MenuItem): component.set_selected(False) menu_item.set_selected(True) def build_panels(self, the_dialog): self.menu_panel = JPanel() self.menu_panel.setLayout(BoxLayout(self.menu_panel, BoxLayout.Y_AXIS)) self.menu_panel.setPreferredSize(Dimension(200, 200)) the_dialog.add(self.menu_panel, BorderLayout.LINE_START) config_panel = JPanel() config_panel.setPreferredSize(Dimension(500, 600)) config_panel.setLayout(BoxLayout(config_panel, BoxLayout.Y_AXIS)) the_dialog.add(config_panel, BorderLayout.CENTER) # Profile properties profile_props_panel = config_dialog.ProfilePropsConfig() profile_props_menu_item = ui_components.MenuItem( "Profile Properties", profile_props_panel) profile_props_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(profile_props_menu_item) config_panel.add(profile_props_panel) # Filters filters_panel = config_dialog.FiltersConfig() filters_menu_item = ui_components.MenuItem("Filters", filters_panel) filters_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(filters_menu_item) config_panel.add(filters_panel) # Rate control rate_panel = config_dialog.RateConfig() rate_menu_item = ui_components.MenuItem("Rate", rate_panel) rate_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(rate_menu_item) config_panel.add(rate_panel) # Delay control delay_panel = config_dialog.DelayConfig() delay_menu_item = ui_components.MenuItem("Delay", delay_panel) delay_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(delay_menu_item) config_panel.add(delay_panel) # Loss control loss_panel = config_dialog.LossConfig() loss_menu_item = ui_components.MenuItem("Loss", loss_panel) loss_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(loss_menu_item) config_panel.add(loss_panel) # Corruption control corrupt_panel = config_dialog.CorruptConfig() corrupt_menu_item = ui_components.MenuItem("Corrupt", corrupt_panel) corrupt_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(corrupt_menu_item) config_panel.add(corrupt_panel) # Duplication control duplicate_panel = config_dialog.DuplicateConfig() duplicate_menu_item = ui_components.MenuItem("Duplicate", duplicate_panel) duplicate_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(duplicate_menu_item) config_panel.add(duplicate_panel) # Reorder control reorder_panel = config_dialog.ReorderConfig() reorder_menu_item = ui_components.MenuItem("Reorder", reorder_panel) reorder_menu_item.addMouseListener(self.MenuMouseListener(self)) self.menu_panel.add(reorder_menu_item) config_panel.add(reorder_panel) # Default selection profile_props_panel.set_selected(True) def initProfilesTable(self): profile_table = JTable() self.profile_table_model = self.ProfileTableModel() profile_table.setModel(self.profile_table_model) cm = profile_table.getColumnModel() # Set column widths for i in range(0, 4): width = self.profile_table_model.column_widths.get(i) if width is not None: column = cm.getColumn(i) column.setPreferredWidth(width) column.setMaxWidth(width) profile_table.setFillsViewportHeight(True) def doAction(event): print event # Add the actions dropdown actionCol = cm.getColumn(3) actions = JComboBox() actions.addItem("Activate") actions.addItem("Unactivate") actions.addItem("Edit") actions.addItem("Export to Script") actions.addItem("Delete") actionCol.setCellEditor(DefaultCellEditor(actions)) self.profile_table_model.actions_combo = actions renderer = self.ComboBoxTableCellRenderer() actionCol.setCellRenderer(renderer) actions.addActionListener(self.ComboActionListener(self)) return profile_table class ComboActionListener(ActionListener): main_frame = None def __init__(self, main_frame): self.main_frame = main_frame def actionPerformed(self, event): if event.getSource().getSelectedIndex() > -1: print event.getSource().getSelectedItem() class ProfileTableModel(AbstractTableModel): columns = ["Name", "Is Active", "Description", "Actions"] column_widths = {0: 200, 1: 100, 2: None, 3: 200} profiles = [] actions_combo = None def __init__(self): # todo temp Load the profiles here profile = Profile() profile.profile_name = "Test profile" profile.profile_descr = "Description for the test profile" test_filter = Filter() test_filter.src_addr = "127.0.0.1" test_filter.src_port = 8089 profile.filters.append(test_filter) self.profiles.append(profile) # todo end temp def getRowCount(self): return len(self.profiles) def getColumnCount(self): return len(self.columns) def getColumnName(self, columnIndex): return self.columns[columnIndex] # Needed to display something other than plain text in the cell def getColumnClass(self, column): # return [String, String, String, JComboBox][column] if column == 3: print self.actions_combo.getClass() return self.actions_combo.getClass() else: return String().getClass() # Jython bug def isCellEditable(self, row, column): if column == 3: return True else: return False def getValueAt(self, rowIndex, columnIndex): # todo update for other columns return { 0: self.profiles[rowIndex].profile_name, 1: self.profiles[rowIndex].active, 2: self.profiles[rowIndex].profile_descr }.get(columnIndex) def addProfile(self, theProfile): self.profiles.append(theProfile) # fireTableCellUpdated(row, col) def removeProfile(self, profile_name): for profile in self.profiles: if profile.profile_name == profile_name: self.profiles.remove(profile) break # todo # fireTableCellUpdated(row, col) class ComboBoxTableCellRenderer(JComboBox, TableCellRenderer): def getTableCellRendererComponent(self, table, value, isSelected, hasFocus, row, column): self.setSelectedItem(value) return self # Handles mouse clicking for all the Edit Profile config options class MenuMouseListener(MouseAdapter): main_frame = None def __init__(self, main_frame): self.main_frame = main_frame def mousePressed(self, event): self.main_frame.show_panel(event.getSource())
stringpart = line[line.index("for") + 3:].strip() oldstring, newstring = stringpart.split(" <=> ") record = Record(compression, oldstring, newstring) records.append(record) numberOfStringPairs = len(records) frame = JFrame("test") frame.setSize(600, 400) panel = JPanel(GridLayout(numberOfStringPairs, 2)) size = Dimension(600, 200 * numberOfStringPairs) panel.setSize(size) panel.setPreferredSize(size) records.sort() for record in records: try: oldname, oldVertices, oldEdges = record.oldstring.split(' ') newname, newVertices, newEdges = record.newstring.split(' ') oldPanel = LinearViewPanel(300, 200) oldPanel.renderVertices(oldVertices) oldPanel.renderEdges(oldEdges) oldPanel.setToolTipText(oldname) panel.add(oldPanel) newPanel = LinearViewPanel(300, 200) newPanel.renderVertices(newVertices)
def __init__(self): self.rw = 0 # table row self.cl = 0 # table column # load hidden files list self.hiddenFiles = ["zzz"] if os.path.exists("hiddenFiles.txt"): fp = open("hiddenFiles.txt", "r") self.hiddenFiles = fp.readlines() fp.close() self.hiddenFiles = [f.strip() for f in self.hiddenFiles] print self.hiddenFiles # These lines setup the basic frame, size and layout # the setDefaultCloseOperation so that only the window closes and not TOPSPIN self.frame = JFrame("Submit NMR Experimets") self.frame.setSize(1200, 440) self.frame.setLayout(BorderLayout()) self.frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) # set up the list and the contents of the list # the python tuple get converted to a Java vector self.data = self.returnCSVlist(self.hiddenFiles) self.list = JList(self.data, valueChanged=self.listSelect) self.spane = JScrollPane() self.spane.setPreferredSize(Dimension(145, 150)) self.spane.getViewport().setView((self.list)) panel = JPanel() panel.add(self.spane) # define buttons bpanel = JPanel() btnS = JButton('Submit File', actionPerformed=self.listSubmit) btnU = JButton('Update List', actionPerformed=self.listUpdate) btnHideFile = JButton('Hide File', actionPerformed=self.listHideFile) btnShowAllFiles = JButton('Show All Files', actionPerformed=self.listShowAllFiles) # label displaying CSV file selected self.label = JLabel('Selected File', JLabel.CENTER) # label to display warnings and confirm expriments submitted self.statusLabel = JLabel('Status', JLabel.CENTER) # Create table to display csv file self.tableData = [] for r in range(18): self.tableData.append([ "", ] * len(JBrukerSubmit.colHeads)) colNames = JBrukerSubmit.colHeads self.dataTableModel = DefaultTableModel(self.tableData, colNames) self.table = JTable(self.dataTableModel, keyTyped=self.tableChangedCB, mouseClicked=self.tableMouseClicked) # set all columns to uneditable except Holder column # print dir(self.table) # self.table.getColumn(0).setEditable(False) # self.table.getColumn(2).setEditable(False) # self.table.getColumn(3).setEditable(False) # self.table.getColumn(4).setEditable(False) # self.table.getColumn(5).setEditable(False) # self.table.getColumn(6).setEditable(False) # self.table = JTable(self.dataTableModel, # keyPressed=self.tableKeyPressedCB) self.scrollPaneTable = JScrollPane() self.scrollPaneTable.setPreferredSize(Dimension(900, 300)) self.scrollPaneTable.getViewport().setView((self.table)) panelTable = JPanel() panelTable.add(self.scrollPaneTable) # create text field to get carousel starting position self.carouselLabel = JLabel("Carousel Position", JLabel.CENTER) self.carouselStartingPosition = JTextField( '1', 13, keyPressed=self.checkCarouselNumber) # add widgets to do with manupulating csv list in FlowLayout Mode panelList = JPanel() panelList.setLayout(FlowLayout()) panelList.setPreferredSize(Dimension(170, 200)) # set preferred size of buttons btnU.setPreferredSize(Dimension(140, 20)) btnS.setPreferredSize(Dimension(140, 20)) btnHideFile.setPreferredSize(Dimension(140, 20)) btnShowAllFiles.setPreferredSize(Dimension(140, 20)) self.carouselLabel.setPreferredSize(Dimension(140, 20)) self.carouselStartingPosition.setPreferredSize(Dimension(170, 20)) panelList.add(btnU) panelList.add(panel) panelList.add(btnHideFile) panelList.add(btnShowAllFiles) panelList.add(JSeparator(JSeparator.HORIZONTAL), BorderLayout.LINE_START) panelList.add(self.carouselLabel) panelList.add(self.carouselStartingPosition) panelList.add(btnS) self.panelLabel = JPanel() self.panelLabel.add(self.label) self.standardBackgroundColor = self.panelLabel.getBackground() # put status label in a panel so that background color can be changed self.panelStatusLabel = JPanel() self.panelStatusLabel.add(self.statusLabel) # add widgets to frame self.frame.add(self.panelLabel, BorderLayout.NORTH) self.frame.add(panelList, BorderLayout.WEST) self.frame.add(panelTable, BorderLayout.CENTER) self.frame.add(self.panelStatusLabel, BorderLayout.SOUTH) self.frame.setVisible(True)
class BurpExtender(IBurpExtender, ITab, IExtensionStateListener): # Define the global variables for the burp plugin EXTENSION_NAME = "UPnP BHunter" ipv4_selected = True services_dict = {} ip_service_dict = {} STOP_THREAD = False #Some SSDP m-search parameters are based upon "UPnP Device Architecture v2.0" SSDP_MULTICAST_IPv4 = ["239.255.255.250"] SSDP_MULTICAST_IPv6 = ["FF02::C", "FF05::C"] SSDP_MULTICAST_PORT = 1900 ST_ALL = "ssdp:all" ST_ROOTDEV = "upnp:rootdevice" PLACEHOLDER = "FUZZ_HERE" SSDP_TIMEOUT = 2 def registerExtenderCallbacks(self, callbacks): # Get a reference to callbacks object self.callbacks = callbacks # Get the useful extension helpers object self.helpers = callbacks.getHelpers() # Set the extension name self.callbacks.setExtensionName(self.EXTENSION_NAME) self.callbacks.registerExtensionStateListener(self) # Draw plugin user interface self.drawPluginUI() self.callbacks.addSuiteTab(self) # Plugin loading message print("[+] Burp plugin UPnP BHunter loaded successfully") return def drawPluginUI(self): # Create the plugin user interface self.pluginTab = JPanel() self.uiTitle = JLabel('UPnP BHunter Load, Aim and Fire Console') self.uiTitle.setFont(Font('Tahoma', Font.BOLD, 14)) self.uiTitle.setForeground(Color(250, 100, 0)) self.uiPanelA = JSplitPane(JSplitPane.VERTICAL_SPLIT) self.uiPanelA.setMaximumSize(Dimension(2500, 1000)) self.uiPanelA.setDividerSize(2) self.uiPanelB = JSplitPane(JSplitPane.VERTICAL_SPLIT) self.uiPanelB.setDividerSize(2) self.uiPanelA.setBottomComponent(self.uiPanelB) self.uiPanelA.setBorder(BorderFactory.createLineBorder(Color.gray)) # Create and configure labels and text fields self.labeltitle_step1 = JLabel("[1st STEP] Discover UPnP Locations") self.labeltitle_step1.setFont(Font('Tahoma', Font.BOLD, 14)) self.labeltitle_step2 = JLabel( "[2nd STEP] Select a UPnP Service and Action") self.labeltitle_step2.setFont(Font('Tahoma', Font.BOLD, 14)) self.labeltitle_step3 = JLabel("[3rd STEP] Time to Attack it") self.labeltitle_step3.setFont(Font('Tahoma', Font.BOLD, 14)) self.labelsubtitle_step1 = JLabel( "Specify the IP version address in scope and start UPnP discovery") self.labelsubtitle_step2 = JLabel( "Select which of the found UPnP services will be probed") self.labelsubtitle_step3 = JLabel( "Review and modify the request, then send it to one of the attack tools" ) self.label_step1 = JLabel("Target IP") self.label_step2 = JLabel("Found UPnp Services") self.labelstatus = JLabel(" Status") self.labelempty_step1 = JLabel(" ") self.labelempty_step2 = JLabel(" ") self.labelupnp = JLabel("UPnP list") self.labelip = JLabel("IP list") self.labelactions = JLabel("Actions") self.labelNoneServiceFound = JLabel(" ") self.labelNoneServiceFound.setFont(Font('Tahoma', Font.BOLD, 12)) self.labelNoneServiceFound.setForeground(Color.red) # Create combobox for IP version selection self.ip_versions = ["IPv4", "IPv6"] self.combo_ipversion = JComboBox(self.ip_versions) self.combo_ipversion.setSelectedIndex(0) self.combo_ipversion.setEnabled(True) # Create and configure progress bar self.progressbar = JProgressBar(0, 100) self.progressbar.setString("Ready") self.progressbar.setStringPainted(True) # Create and configure buttons self.startbutton = JButton("Start Discovery", actionPerformed=self.startHunting) self.clearbutton = JButton("Clear All", actionPerformed=self.clearAll) self.intruderbutton = JButton("Send to Intruder", actionPerformed=self.sendToIntruder) self.repeaterbutton = JButton("Send to Repeater", actionPerformed=self.sendToRepeater) #self.WANrepeaterbutton = JButton("to Repeater", actionPerformed=self.sendWANUPnPToRepeater) self.textarea_request = JTextArea(18, 90) self.intruderbutton.setEnabled(False) self.repeaterbutton.setEnabled(False) # Class neeeded to handle the target combobox in second step panel class TargetComboboxListener(ActionListener): def __init__(self, upnpcombo_targets, upnpcombo_services, ip_service_dict): self.upnpcombo_targets = upnpcombo_targets self.upnpcombo_services = upnpcombo_services self.ip_service_dict = ip_service_dict def actionPerformed(self, event): try: # Update the location url combobox depending on the IP combobox selected_target = self.upnpcombo_targets.getSelectedItem() if self.ip_service_dict and selected_target: self.upnpcombo_services.removeAllItems() for service_url in self.ip_service_dict[ selected_target]: self.upnpcombo_services.addItem(service_url) self.upnpcombo_services.setSelectedIndex(0) except BaseException as e: print("[!] Exception selecting service: \"%s\" ") % e # Class neeeded to handle the service combobox in second step panel class ServiceComboboxListener(ActionListener): def __init__(self, upnpcombo_services, upnpcombo_actions, services_dict): self.upnpcombo_services = upnpcombo_services self.upnpcombo_actions = upnpcombo_actions self.services = services_dict def actionPerformed(self, event): try: # Update the location url combobox depending on the IP combobox selected_service = self.upnpcombo_services.getSelectedItem( ) if self.services and selected_service: self.upnpcombo_actions.removeAllItems() actions = self.services[selected_service] for action in actions: self.upnpcombo_actions.addItem(action) self.upnpcombo_actions.setSelectedIndex(0) except BaseException as e: print("[!] Exception selecting service: \"%s\" ") % e # Class neeeded to handle the action combobox in second step panel class ActionComboboxListener(ActionListener): def __init__(self, upnpcombo_services, upnpcombo_actions, textarea_request, services_dict): self.upnpcombo_services = upnpcombo_services self.upnpcombo_actions = upnpcombo_actions self.textarea_request = textarea_request self.services = services_dict def actionPerformed(self, event): try: # Update the location url combobox depending on the IP combobox selected_action = self.upnpcombo_actions.getSelectedItem() selected_service = self.upnpcombo_services.getSelectedItem( ) if self.services and selected_action: self.textarea_request.setText( self.services[selected_service][selected_action]) except BaseException as e: print("[!] Exception selecting action: \"%s\" ") % e self.upnpactions = [" "] self.upnpcombo_actions = JComboBox(self.upnpactions) self.upnpcombo_actions.setSelectedIndex(0) self.upnpcombo_actions.setEnabled(False) # Create the combo box, select item at index 0 (first item in list) self.upnpservices = [" "] self.upnpcombo_services = JComboBox(self.upnpservices) self.upnpcombo_services.setSelectedIndex(0) self.upnpcombo_services.setEnabled(False) # Create the combo box, select item at index 0 (first item in list) self.upnptargets = [" "] self.upnpcombo_targets = JComboBox(self.upnptargets) self.upnpcombo_targets.setSelectedIndex(0) self.upnpcombo_targets.setEnabled(False) # Set the action listeners for all the comboboxes self.upnpcombo_targets.addActionListener( TargetComboboxListener(self.upnpcombo_targets, self.upnpcombo_services, self.ip_service_dict)) self.upnpcombo_services.addActionListener( ServiceComboboxListener(self.upnpcombo_services, self.upnpcombo_actions, self.services_dict)) self.upnpcombo_actions.addActionListener( ActionComboboxListener(self.upnpcombo_services, self.upnpcombo_actions, self.textarea_request, self.services_dict)) # Configuring first step panel self.panel_step1 = JPanel() self.panel_step1.setPreferredSize(Dimension(2250, 100)) self.panel_step1.setBorder(EmptyBorder(10, 10, 10, 10)) self.panel_step1.setLayout(BorderLayout(15, 15)) self.titlepanel_step1 = JPanel() self.titlepanel_step1.setLayout(BorderLayout()) self.titlepanel_step1.add(self.labeltitle_step1, BorderLayout.NORTH) self.titlepanel_step1.add(self.labelsubtitle_step1) self.targetpanel_step1 = JPanel() self.targetpanel_step1.add(self.label_step1) self.targetpanel_step1.add(self.combo_ipversion) self.targetpanel_step1.add(self.startbutton) self.targetpanel_step1.add(self.clearbutton) self.targetpanel_step1.add(self.labelstatus) self.targetpanel_step1.add(self.progressbar) self.emptypanel_step1 = JPanel() self.emptypanel_step1.setLayout(BorderLayout()) self.emptypanel_step1.add(self.labelempty_step1, BorderLayout.WEST) # Assembling first step panel components self.panel_step1.add(self.titlepanel_step1, BorderLayout.NORTH) self.panel_step1.add(self.targetpanel_step1, BorderLayout.WEST) self.panel_step1.add(self.emptypanel_step1, BorderLayout.SOUTH) self.uiPanelA.setTopComponent(self.panel_step1) # Configure second step panel self.panel_step2 = JPanel() self.panel_step2.setPreferredSize(Dimension(2250, 100)) self.panel_step2.setBorder(EmptyBorder(10, 10, 10, 10)) self.panel_step2.setLayout(BorderLayout(15, 15)) self.titlepanel_step2 = JPanel() self.titlepanel_step2.setLayout(BorderLayout()) self.titlepanel_step2.add(self.labeltitle_step2, BorderLayout.NORTH) self.titlepanel_step2.add(self.labelsubtitle_step2) self.selectpanel_step2 = JPanel() self.selectpanel_step2.add(self.labelip) self.selectpanel_step2.add(self.upnpcombo_targets) self.selectpanel_step2.add(self.labelupnp) self.selectpanel_step2.add(self.upnpcombo_services) self.selectpanel_step2.add(self.labelactions) self.selectpanel_step2.add(self.upnpcombo_actions) self.emptypanel_step2 = JPanel() self.emptypanel_step2.setLayout(BorderLayout()) self.emptypanel_step2.add(self.labelempty_step2, BorderLayout.WEST) self.emptypanel_step2.add(self.labelNoneServiceFound) # Assembling second step panel components self.panel_step2.add(self.titlepanel_step2, BorderLayout.NORTH) self.panel_step2.add(self.selectpanel_step2, BorderLayout.WEST) self.panel_step2.add(self.emptypanel_step2, BorderLayout.SOUTH) self.uiPanelB.setTopComponent(self.panel_step2) # Configuring third step panel self.panel_step3 = JPanel() self.panel_step3.setPreferredSize(Dimension(2250, 100)) self.panel_step3.setBorder(EmptyBorder(10, 10, 10, 10)) self.panel_step3.setLayout(BorderLayout(15, 15)) self.titlepanel_step3 = JPanel() self.titlepanel_step3.setLayout(BorderLayout()) self.titlepanel_step3.add(self.labeltitle_step3, BorderLayout.NORTH) self.titlepanel_step3.add(self.labelsubtitle_step3) self.underpanel_step3 = JPanel() self.underpanel_step3.setLayout(BorderLayout()) self.underpanel_step3.add((JScrollPane(self.textarea_request)), BorderLayout.NORTH) self.actionpanel_step3 = JPanel() self.actionpanel_step3.add(self.intruderbutton) self.actionpanel_step3.add(self.repeaterbutton) self.extrapanel_step3 = JPanel() self.extrapanel_step3.setLayout(BorderLayout()) self.extrapanel_step3.add(self.actionpanel_step3, BorderLayout.WEST) # Assembling thirdd step panel components self.panel_step3.add(self.titlepanel_step3, BorderLayout.NORTH) self.panel_step3.add(self.underpanel_step3, BorderLayout.WEST) self.panel_step3.add(self.extrapanel_step3, BorderLayout.SOUTH) self.uiPanelB.setBottomComponent(self.panel_step3) # Assembling the group of all panels layout = GroupLayout(self.pluginTab) self.pluginTab.setLayout(layout) layout.setHorizontalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup( layout.createSequentialGroup().addGap(10, 10, 10).addGroup( layout.createParallelGroup( GroupLayout.Alignment.LEADING).addComponent( self.uiTitle).addGap(15, 15, 15).addComponent( self.uiPanelA)).addContainerGap( 26, Short.MAX_VALUE))) layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup( layout.createSequentialGroup().addGap(15, 15, 15).addComponent( self.uiTitle).addGap(15, 15, 15).addComponent( self.uiPanelA).addGap(20, 20, 20).addGap(20, 20, 20))) def extensionUnloaded(self): # Unload the plugin, and if running stop the background thread if self.upnpcombo_services.isEnabled(): if self.th.isAlive(): print("[+] Stopping thread %s") % self.th.getName() self.STOP_THREAD = True self.th.join() else: print("Thread %s already dead") % self.th.getName() print("[+] Burp plugin UPnP BHunter successfully unloaded") return def getTabCaption(self): return self.EXTENSION_NAME def getUiComponent(self): return self.pluginTab def clearAll(self, e=None): # Reset all data of the plugin self.services_dict.clear() self.progressbar.setString("Ready") self.progressbar.setValue(0) self.upnpcombo_targets.removeAllItems() self.upnpcombo_targets.setEnabled(False) self.upnpcombo_services.removeAllItems() self.upnpcombo_services.setEnabled(False) self.upnpcombo_actions.removeAllItems() self.upnpcombo_actions.setEnabled(False) self.intruderbutton.setEnabled(False) self.repeaterbutton.setEnabled(False) self.labelNoneServiceFound.setText(" ") self.textarea_request.setText(" ") print("[+] Clearing all data") return def startHunting(self, e=None): # Starting the UPnP hunt def startHunting_run(): # Initialize the internal parameters every time the start-discovery button is clicked self.services_dict.clear() found_loc = [] discovery_files = [] self.labelNoneServiceFound.setText(" ") self.intruderbutton.setEnabled(False) self.repeaterbutton.setEnabled(False) # Then determine if targerting IPv4 or IPv6 adresses if self.combo_ipversion.getSelectedItem() == "IPv4": self.ipv4_selected = True print("[+] Selected IPv4 address scope") else: self.ipv4_selected = False print("[+] Selected IPv6 address scope") # And here finally the hunt could start self.progressbar.setString("Running...") self.progressbar.setValue(20) found_loc = self.discoverUpnpLocations() self.progressbar.setValue(40) discovery_files = self.downloadXMLfiles(found_loc) self.progressbar.setValue(60) self.buildSOAPs(discovery_files) self.progressbar.setValue(80) self.progressbar.setString("Done") self.progressbar.setValue(100) self.updateComboboxList(self.services_dict) # Update the comboboxes list with the discovered UPnPs if (self.services_dict): self.upnpcombo_targets.setEnabled(True) self.upnpcombo_services.setEnabled(True) self.upnpcombo_actions.setEnabled(True) self.intruderbutton.setEnabled(True) self.repeaterbutton.setEnabled(True) if self.STOP_THREAD: return # Start a background thread to run the above nested function in order to prevent the blocking of plugin UI self.th = threading.Thread(target=startHunting_run) #self.th.daemon = True # This does not seem to be useful self.th.setName("th-BHunter") self.th.start() def ssdpReqBuilder(self, ssdp_timeout, st_type, ssdp_ip, ssdp_port): # Builder of the two ssdp msearch request types msearch_req = "M-SEARCH * HTTP/1.1\r\n" \ "HOST: {0}:{1}\r\n" \ "MAN: \"ssdp:discover\"\r\n" \ "MX: {2}\r\n" \ "ST: {3}\r\n" \ "\r\n" \ .format(ssdp_ip, ssdp_port, ssdp_timeout, st_type) return msearch_req def sendMsearch(self, ssdp_req, ssdp_ip, ssdp_port): # Send the ssdp request and retrieve response buf_resp = set() if self.ipv4_selected: print("[+] Creating IPv4 SSDP multicast request") sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) else: print("[+] Creating IPv6 SSDP multicast request") sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) sock.setblocking(0) # Sending ssdp requests while len(ssdp_req): # Blocking socket client until the request is completely sent try: sent = sock.sendto(ssdp_req.encode("ASCII"), (ssdp_ip, ssdp_port)) ssdp_req = ssdp_req[sent:] except socket.error, exc: if exc.errno != errno.EAGAIN: print("[E] Got error %s with socket when sending") % exc sock.close() raise exc print("[!] Blocking socket until ", len(ssdp_req), " is sent.") select.select([], [sock], []) continue # Retrieving ssdp responses num_resp = 0 while sock: # Blocking socket until there are ssdp responses to be read or timeout is reached readable, __, __ = select.select([sock], [], [], self.SSDP_TIMEOUT) if not readable: # Timeout reached without receiving any ssdp response if num_resp == 0: print( "[!] Got timeout without receiving any ssdp response.") break else: num_resp = num_resp + 1 # Almost an ssdp response was received if readable[0]: try: data = sock.recv(1024) if data: buf_resp.add(data.decode('ASCII')) except socket.error, exc: print("[E] Got error %s with socket when receiving" ) % exc sock.close() raise exc
class MyPanel(JSplitPane): def __init__(self, scannerInstance): self.scannerInstance = scannerInstance JSplitPane.__init__(self, JSplitPane.VERTICAL_SPLIT) # super(MyPanel, self).__init__(self, JSplitPane.VERTICAL_SPLIT) # self.setSize(640, 460) self.setBorder(EmptyBorder(20, 20, 20, 20)) self.topPanel = JPanel(BorderLayout(10, 10)) self.topPanel.setBorder(EmptyBorder(0, 0, 10, 0)) # self.topPanel.setBackground(Color.blue) self.bottomPanel = JPanel() self.bottomPanel.setBorder(EmptyBorder(10, 0, 0, 0)) # self.bottomPanel.setBackground(Color.yellow) self.bottomPanel.setPreferredSize(Dimension(580, 40)) # plain self.plainPanel = JPanel(BorderLayout(10, 10)) self.plainTextPane = JTextArea() self.plainTextPane.setLineWrap(True) self.plainTextPane.setEditable(True) self.plainScrollPane = JScrollPane(self.plainTextPane) self.plainScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER) self.plainPanel.add(JLabel("PLAIN:", SwingConstants.CENTER), BorderLayout.PAGE_START) self.plainPanel.add(self.plainScrollPane, BorderLayout.CENTER) self.topPanel.add(self.plainPanel, BorderLayout.LINE_START) # button self.btnsPanel = JPanel(GridBagLayout()) gbc = GridBagConstraints() gbc.fill = GridBagConstraints.HORIZONTAL gbc.gridx = 0 gbc.gridy = 0 self.btnsPanel.add(JButton("=Encrypt=>", actionPerformed=self.encrypt), gbc) gbc.fill = GridBagConstraints.HORIZONTAL gbc.gridx = 0 gbc.gridy = 1 self.btnsPanel.add(JButton("<=Decrypt=", actionPerformed=self.decrypt), gbc) gbc.fill = GridBagConstraints.HORIZONTAL gbc.gridx = 0 gbc.gridy = 2 gbc.gridheight = 2 gbc.ipadx = 10 self.btnsPanel.add(JButton("SIGN", actionPerformed=self.sign), gbc) # b_enc.setPreferredSize(Dimension(30, 20)) # b_dec.setPreferredSize(Dimension(30, 20)) self.topPanel.add(self.btnsPanel, BorderLayout.CENTER) # cipher self.cipherPanel = JPanel(BorderLayout(10, 10)) self.cipherTextPane = JTextArea() self.cipherTextPane.setLineWrap(True) self.cipherTextPane.setEditable(True) self.cipherScrollPane = JScrollPane(self.cipherTextPane) self.cipherScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER) self.cipherPanel.add(JLabel("CIPHER:", SwingConstants.CENTER), BorderLayout.PAGE_START) self.cipherPanel.add(self.cipherScrollPane, BorderLayout.CENTER) self.topPanel.add(self.cipherPanel, BorderLayout.LINE_END) self.signPanel = JPanel(FlowLayout(FlowLayout.LEADING, 10, 10)) self.signPanel.add(JLabel("SIGN:", SwingConstants.LEFT), BorderLayout.LINE_START) self.signField = JTextField(50) self.signPanel.add(self.signField) self.bottomPanel.add(self.signPanel) self.plainPanel.setPreferredSize(Dimension(260, 400)) self.btnsPanel.setPreferredSize(Dimension(80, 400)) self.cipherPanel.setPreferredSize(Dimension(260, 400)) self.setTopComponent(self.topPanel) self.setBottomComponent(self.bottomPanel) def setPlain(self, plain): if plain: self.plainTextPane.setText(plain.decode("utf-8")) def setCipher(self, cipher): self.cipherTextPane.setText(cipher) def setSignature(self, sign): self.signField.setText(sign) def unicode_to_str(self, content): data = "" for i in content: data += chr(ord(i)) return data def get_real_content(self, content): s_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) handled_cnt = None data = self.unicode_to_str(content) try: s_client.connect(LOCAL_IPC) s_client.send(data) handled_cnt = "" while True: _sp = s_client.recv(1024) if _sp and len(_sp) > 0: handled_cnt += _sp if len(_sp) < 1024: break else: break except socket.error: BP_STDERR.println("fail to connect local IPC service.") s_client.close() # BP_STDOUT.println("get_real_content - %s" % handled_cnt.decode("utf-8")) return handled_cnt if handled_cnt and len(handled_cnt) > 0 else None def encrypt(self, event): plain = self.plainTextPane.getText() # BP_STDERR.println("plain type - %s" % type(plain)) result = self.get_real_content(b"\x01" + plain) self.setCipher(result) def decrypt(self, event, is_req=None): cipher = self.cipherTextPane.getText() # BP_STDERR.println("cipher type - %s" % type(cipher)) flag = b"\x02" if is_req is True else b"\x03" if is_req is False else b"\x00" result = self.get_real_content(flag + cipher) self.setPlain(result) def sign(self, event): text = self.plainTextPane.getText() # BP_STDERR.println("sign func called! - %s" % text) result = self.get_real_content(b"\x04" + text) self.setSignature(result)
class Config(ITab): """Defines the Configuration tab""" def __init__(self, callbacks, parent): # Initialze self stuff self._callbacks = callbacks self.config = {} self.ext_stats = {} self.url_reqs = [] self.parse_files = False self.tab = JPanel(GridBagLayout()) self.view_port_text = JTextArea("===SpyDir===") self.delim = JTextField(30) self.ext_white_list = JTextField(30) # I'm not sure if these fields are necessary still # why not just use Burp func to handle this? # leaving them in case I need it for the HTTP handler later # self.cookies = JTextField(30) # self.headers = JTextField(30) self.url = JTextField(30) self.parent_window = parent self.plugins = {} self.loaded_p_list = set() self.loaded_plugins = False self.config['Plugin Folder'] = None self.double_click = False self.source_input = "" self.print_stats = True self.curr_conf = JLabel() self.window = JFrame("Select plugins", preferredSize=(200, 250), windowClosing=self.p_close) self.window.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE) self.window.setVisible(False) self.path_vars = JTextField(30) # Initialize local stuff tab_constraints = GridBagConstraints() status_field = JScrollPane(self.view_port_text) # Configure view port self.view_port_text.setEditable(False) labels = self.build_ui() # Add things to rows tab_constraints.anchor = GridBagConstraints.FIRST_LINE_END tab_constraints.gridx = 1 tab_constraints.gridy = 0 tab_constraints.fill = GridBagConstraints.HORIZONTAL self.tab.add(JButton( "Resize screen", actionPerformed=self.resize), tab_constraints) tab_constraints.gridx = 0 tab_constraints.gridy = 1 tab_constraints.anchor = GridBagConstraints.FIRST_LINE_START self.tab.add(labels, tab_constraints) tab_constraints.gridx = 1 tab_constraints.gridy = 1 tab_constraints.fill = GridBagConstraints.BOTH tab_constraints.weightx = 1.0 tab_constraints.weighty = 1.0 tab_constraints.anchor = GridBagConstraints.FIRST_LINE_END self.tab.add(status_field, tab_constraints) try: self._callbacks.customizeUiComponent(self.tab) except Exception: pass def build_ui(self): """Builds the configuration screen""" labels = JPanel(GridLayout(21, 1)) checkbox = JCheckBox("Attempt to parse files for URL patterns?", False, actionPerformed=self.set_parse) stats_box = JCheckBox("Show stats?", True, actionPerformed=self.set_show_stats) # The two year old in me is laughing heartily plug_butt = JButton("Specify plugins location", actionPerformed=self.set_plugin_loc) load_plug_butt = JButton("Select plugins", actionPerformed=self.p_build_ui) parse_butt = JButton("Parse directory", actionPerformed=self.parse) clear_butt = JButton("Clear text", actionPerformed=self.clear) spider_butt = JButton("Send to Spider", actionPerformed=self.scan) save_butt = JButton("Save config", actionPerformed=self.save) rest_butt = JButton("Restore config", actionPerformed=self.restore) source_butt = JButton("Input Source File/Directory", actionPerformed=self.get_source_input) # Build grid labels.add(source_butt) labels.add(self.curr_conf) labels.add(JLabel("String Delimiter:")) labels.add(self.delim) labels.add(JLabel("Extension Whitelist:")) labels.add(self.ext_white_list) labels.add(JLabel("URL:")) labels.add(self.url) labels.add(JLabel("Path Variables")) labels.add(self.path_vars) # Leaving these here for now. # labels.add(JLabel("Cookies:")) # labels.add(self.cookies) # labels.add(JLabel("HTTP Headers:")) # labels.add(self.headers) labels.add(checkbox) labels.add(stats_box) labels.add(plug_butt) labels.add(parse_butt) labels.add(JButton("Show all endpoints", actionPerformed=self.print_endpoints)) labels.add(clear_butt) labels.add(spider_butt) labels.add(JLabel("")) labels.add(save_butt) labels.add(rest_butt) labels.add(load_plug_butt) # Tool tips! self.delim.setToolTipText("Use to manipulate the final URL. " "See About tab for example.") self.ext_white_list.setToolTipText("Define a comma delimited list of" " file extensions to parse. Use *" " to parse all files.") self.url.setToolTipText("Enter the target URL") checkbox.setToolTipText("Parse files line by line using plugins" " to enumerate language/framework specific" " endpoints") parse_butt.setToolTipText("Attempt to enumerate application endpoints") clear_butt.setToolTipText("Clear status window and the parse results") spider_butt.setToolTipText("Process discovered endpoints") save_butt.setToolTipText("Saves the current config settings") rest_butt.setToolTipText("<html>Restores previous config settings:" "<br/>-Input Directory<br/>-String Delim" "<br/>-Ext WL<br/>-URL<br/>-Plugins") source_butt.setToolTipText("Select the application's " "source directory or file to parse") self.path_vars.setToolTipText("Supply a JSON object with values" "for dynamically enumerated query" "string variables") return labels def set_url(self, menu_url): """Changes the configuration URL to the one from the menu event""" self.url.setText(menu_url) # Event functions def set_parse(self, event): """ Handles the click event from the UI checkbox to attempt code level parsing """ self.parse_files = not self.parse_files if self.parse_files: if not self.loaded_plugins: self._plugins_missing_warning() def restore(self, event): """Attempts to restore the previously saved configuration.""" jdump = None try: jdump = loads(self._callbacks.loadExtensionSetting("config")) except Exception as exc: # Generic exception thrown directly to user self.update_scroll( "[!!] Error during restore!\n\tException: %s" % str(exc)) if jdump is not None: self.url.setText(jdump.get('URL')) # self.cookies.setText(jdump.get('Cookies')) # self.headers.setText(jdump.get("Headers")) ewl = "" for ext in jdump.get('Extension Whitelist'): ewl += ext + ", " self.ext_white_list.setText(ewl[:-2]) self.delim.setText(jdump.get('String Delimiter')) self.source_input = jdump.get("Input Directory") self.config['Plugin Folder'] = jdump.get("Plugin Folder") if (self.config['Plugin Folder'] is not None and (len(self.plugins.values()) < 1)): self._load_plugins(self.config['Plugin Folder']) self._update() self.update_scroll("[^] Restore complete!") else: self.update_scroll("[!!] Restore failed!") def save(self, event=None): """ Saves the configuration details to a Burp Suite's persistent store. """ self._update() try: if not self._callbacks.isInScope(URL(self.url.getText())): self.update_scroll("[!!] URL provided is NOT in Burp Scope!") except MalformedURLException: # If url field is blank we'll pass # still save the settings. try: self._callbacks.saveExtensionSetting("config", dumps(self.config)) self.update_scroll("[^] Settings saved!") except Exception: self.update_scroll("[!!] Error saving settings to Burp Suite!") def parse(self, event): """ Handles the click event from the UI. Attempts to parse the given directory (and/or source files) for url endpoints Saves the items found within the url_reqs list """ self._update() file_set = set() fcount = 0 other_dirs = set() self.ext_stats = {} if self.loaded_plugins: self.update_scroll("[^] Attempting to parse files" + " for URL patterns. This might take a minute.") if path.isdir(self.source_input): for dirname, _, filenames in walk(self.source_input): for filename in filenames: fcount += 1 ext = path.splitext(filename)[1] count = self.ext_stats.get(ext, 0) + 1 filename = "%s/%s" % (dirname, filename) self.ext_stats.update({ext: count}) if self.parse_files and self._ext_test(ext): # i can haz threading? file_set.update(self._code_as_endpoints(filename, ext)) elif self._ext_test(ext): r_files, oths = self._files_as_endpoints(filename, ext) file_set.update(r_files) other_dirs.update(oths) elif path.isfile(self.source_input): ext = path.splitext(self.source_input)[1] file_set.update(self._code_as_endpoints(self.source_input, ext)) else: self.update_scroll("[!!] Input Directory is not valid!") if len(other_dirs) > 0: self.update_scroll("[*] Found files matching file extension in:\n") for other_dir in other_dirs: self.update_scroll(" " * 4 + "%s\n" % other_dir) self._handle_path_vars(file_set) self._print_parsed_status(fcount) return (other_dirs, self.url_reqs) def _handle_path_vars(self, file_set): proto = 'http://' for item in file_set: if item.startswith("http://") or item.startswith("https://"): proto = item.split("//")[0] + '//' item = item.replace(proto, "") item = self._path_vars(item) self.url_reqs.append(proto + item.replace('//', '/')) def _path_vars(self, item): p_vars = None if self.path_vars.getText(): try: p_vars = loads(str(self.path_vars.getText())) except: self.update_scroll("[!] Error reading supplied Path Variables!") if p_vars is not None: rep_str = "" try: for k in p_vars.keys(): rep_str += "[^] Replacing %s with %s!\n" % (k, str(p_vars.get(k))) self.update_scroll(rep_str) for k in p_vars.keys(): if str(k) in item: item = item.replace(k, str(p_vars.get(k))) except AttributeError: self.update_scroll("[!] Error reading supplied Path Variables! This needs to be a JSON dictionary!") return item def scan(self, event): """ handles the click event from the UI. Adds the given URL to the burp scope and sends the requests to the burp spider """ temp_url = self.url.getText() if not self._callbacks.isInScope(URL(temp_url)): if not self.double_click: self.update_scroll("[!!] URL is not in scope! Press Send to " "Spider again to add to scope and scan!") self.double_click = True return else: self._callbacks.sendToSpider(URL(temp_url)) self.update_scroll( "[^] Sending %d requests to Spider" % len(self.url_reqs)) for req in self.url_reqs: self._callbacks.sendToSpider(URL(req)) def clear(self, event): """Clears the viewport and the current parse exts""" self.view_port_text.setText("===SpyDir===") self.ext_stats = {} def print_endpoints(self, event): """Prints the discovered endpoints to the status window.""" req_str = "" if len(self.url_reqs) > 0: self.update_scroll("[*] Printing all discovered endpoints:") for req in sorted(self.url_reqs): req_str += " %s\n" % req else: req_str = "[!!] No endpoints discovered" self.update_scroll(req_str) def set_show_stats(self, event): """Modifies the show stats setting""" self.print_stats = not self.print_stats def get_source_input(self, event): """Sets the source dir/file for parsing""" source_chooser = JFileChooser() source_chooser.setFileSelectionMode( JFileChooser.FILES_AND_DIRECTORIES) source_chooser.showDialog(self.tab, "Choose Source Location") chosen_source = source_chooser.getSelectedFile() try: self.source_input = chosen_source.getAbsolutePath() except AttributeError: pass if self.source_input is not None: self.update_scroll("[*] Source location: %s" % self.source_input) self.curr_conf.setText(self.source_input) # Plugin functions def _parse_file(self, filename, file_url): """ Attempts to parse a file with the loaded plugins Returns set of endpoints """ file_set = set() with open(filename, 'r') as plug_in: lines = plug_in.readlines() ext = path.splitext(filename)[1].upper() if ext in self.plugins.keys() and self._ext_test(ext): for plug in self.plugins.get(ext): if plug.enabled: res = plug.run(lines) if len(res) > 0: for i in res: i = file_url + i file_set.add(i) elif ext == '.TXT' and self._ext_test(ext): for i in lines: i = file_url + i file_set.add(i.strip()) return file_set def set_plugin_loc(self, event): """Attempts to load plugins from a specified location""" if self.config['Plugin Folder'] is not None: choose_plugin_location = JFileChooser(self.config['Plugin Folder']) else: choose_plugin_location = JFileChooser() choose_plugin_location.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY) choose_plugin_location.showDialog(self.tab, "Choose Folder") chosen_folder = choose_plugin_location.getSelectedFile() self.config['Plugin Folder'] = chosen_folder.getAbsolutePath() self._load_plugins(self.config['Plugin Folder']) def _load_plugins(self, folder): """ Parses a local directory to get the plugins related to code level scanning """ report = "" if len(self.plugins.keys()) > 0: report = "[^] Plugins reloaded!" for _, _, filenames in walk(folder): for p_name in filenames: n_e = path.splitext(p_name) # n_e = name_extension if n_e[1] == ".py": f_loc = "%s/%s" % (folder, p_name) loaded_plug = self._validate_plugin(n_e[0], f_loc) if loaded_plug: for p in self.loaded_p_list: if p.get_name() == loaded_plug.get_name(): self.loaded_p_list.discard(p) self.loaded_p_list.add(loaded_plug) if not report.startswith("[^]"): report += "%s loaded\n" % loaded_plug.get_name() self._dictify(self.loaded_p_list) if len(self.plugins.keys()) > 0: self.loaded_plugins = True else: report = "[!!] Plugins load failure" self.loaded_plugins = False self.update_scroll(report) return report def _validate_plugin(self, p_name, f_loc): """ Attempts to verify the manditory plugin functions to prevent broken plugins from loading. Generates an error message if plugin does not contain an appropriate function. """ # Load the plugin try: plug = load_source(p_name, f_loc) except Exception as exc: # this needs to be generic. self.update_scroll( "[!!] Error loading: %s\n\tType:%s Error: %s" % (f_loc, type(exc), str(exc))) # Verify the plugin's functions funcs = dir(plug) err = [] if "get_name" not in funcs: err.append("get_name()") if "get_ext" not in funcs: err.append("get_ext()") if "run" not in funcs: err.append("run()") # Report errors & return if len(err) < 1: return Plugin(plug, True) for issue in err: self.update_scroll("[!!] %s is missing: %s func" % (p_name, issue)) return None def _dictify(self, plist): """Converts the list of loaded plugins (plist) into a dictionary""" for p in plist: exts = p.get_ext().upper() for ext in exts.split(","): prev_load = self.plugins.get(ext, []) prev_load.append(p) self.plugins[ext] = prev_load # Status window functions def _print_parsed_status(self, fcount): """Prints the parsed directory status information""" if self.parse_files and not self.loaded_plugins: self._plugins_missing_warning() if len(self.url_reqs) > 0: self.update_scroll("[*] Example URL: %s" % self.url_reqs[0]) if self.print_stats: report = (("[*] Found: %r files to be requested.\n\n" + "[*] Stats: \n " + "Found: %r files.\n") % (len(self.url_reqs), fcount)) if len(self.ext_stats) > 0: report += ("[*] Extensions found: %s" % str(dumps(self.ext_stats, sort_keys=True, indent=4))) else: report = ("[*] Found: %r files to be requested.\n" % len(self.url_reqs)) self.update_scroll(report) return report def _plugins_missing_warning(self): """Prints a warning message""" self.update_scroll("[!!] No plugins loaded!") def update_scroll(self, text): """Updates the view_port_text with the new information""" temp = self.view_port_text.getText().strip() if text not in temp or text[0:4] == "[!!]": self.view_port_text.setText("%s\n%s" % (temp, text)) elif not temp.endswith("[^] Status unchanged"): self.view_port_text.setText("%s\n[^] Status unchanged" % temp) # Internal functions def _code_as_endpoints(self, filename, ext): file_set = set() file_url = self.config.get("URL") if self.loaded_plugins or ext == '.txt': if self._ext_test(ext): file_set.update( self._parse_file(filename, file_url)) else: file_set.update( self._parse_file(filename, file_url)) return file_set def _files_as_endpoints(self, filename, ext): """Generates endpoints via files with the appropriate extension(s)""" file_url = self.config.get("URL") broken_splt = "" other_dirs = set() # directories outside of the String Delim. file_set = set() str_del = self.config.get("String Delimiter") if not str_del: self.update_scroll("[!!] No available String Delimiter!") return spl_str = filename.split(str_del) try: # Fix for index out of bounds exception while parsing # subfolders _not_ included by the split if len(spl_str) > 1: file_url += ((spl_str[1]) .replace('\\', '/')) else: broken_splt = filename.split(self.source_input)[1] other_dirs.add(broken_splt) except Exception as exc: # Generic exception thrown directly to user self.update_scroll("[!!] Error parsing: " + "%s\n\tException: %s" % (filename, str(exc))) if self._ext_test(ext): if file_url != self.config.get("URL"): file_set.add(file_url) else: other_dirs.discard(broken_splt) return file_set, other_dirs def _ext_test(self, ext): """Litmus test for extension whitelist""" val = False if "*" in self.config.get("Extension Whitelist"): val = True else: val = (len(ext) > 0 and (ext.strip().upper() in self.config.get("Extension Whitelist"))) return val def _update(self): """Updates internal data""" self.config["Input Directory"] = self.source_input self.config["String Delimiter"] = self.delim.getText() white_list_text = self.ext_white_list.getText() self.config["Extension Whitelist"] = white_list_text.upper().split(',') file_url = self.url.getText() if not (file_url.startswith('https://') or file_url.startswith('http://')): self.update_scroll("[!] Assuming protocol! Default value: 'http://'") file_url = 'http://' + file_url self.url.setText(file_url) if not file_url.endswith('/') and file_url != "": file_url += '/' self.config["URL"] = file_url # self.config["Cookies"] = self.cookies.getText() # self.config["Headers"] = self.headers.getText() del self.url_reqs[:] self.curr_conf.setText(self.source_input) # Window sizing functions def resize(self, event): """Resizes the window to better fit Burp""" if self.parent_window is not None: par_size = self.parent_window.getSize() par_size.setSize(par_size.getWidth() * .99, par_size.getHeight() * .9) self.tab.setPreferredSize(par_size) self.parent_window.validate() self.parent_window.switch_focus() def p_close(self, event): """ Handles the window close event. """ self.window.setVisible(False) self.window.dispose() def p_build_ui(self, event): """ Adds a list of checkboxes, one for each loaded plugin to the Selct plugins window """ if not self.loaded_p_list: self.update_scroll("[!!] No plugins loaded!") return scroll_pane = JScrollPane() scroll_pane.setPreferredSize(Dimension(200, 250)) check_frame = JPanel(GridBagLayout()) constraints = GridBagConstraints() constraints.fill = GridBagConstraints.HORIZONTAL constraints.gridy = 0 constraints.anchor = GridBagConstraints.FIRST_LINE_START for plug in self.loaded_p_list: check_frame.add(JCheckBox(plug.get_name(), plug.enabled, actionPerformed=self.update_box), constraints) constraints.gridy += 1 vport = JViewport() vport.setView(check_frame) scroll_pane.setViewport(vport) self.window.contentPane.add(scroll_pane) self.window.pack() self.window.setVisible(True) def update_box(self, event): """ Handles the check/uncheck event for the plugin's box. """ for plug in self.loaded_p_list: if plug.get_name() == event.getActionCommand(): plug.enabled = not plug.enabled if plug.enabled: self.update_scroll("[^] Enabled: %s" % event.getActionCommand()) else: self.update_scroll("[^] Disabled: %s" % event.getActionCommand()) # ITab required functions @staticmethod def getTabCaption(): """Returns the name of the Burp Suite Tab""" return "SpyDir" def getUiComponent(self): """Returns the UI component for the Burp Suite tab""" return self.tab
def reloadComponent(game,dialog,node): c = None text = node.getAttribute("text") if node.hasAttribute("text") else "" align = int(node.getAttribute("align")) if node.hasAttribute("align") else 0 #Components if node.nodeName=="jpanel": c = JPanel() c.setBackground(Color.BLACK) layout = createLayoutManager(c,node.getAttribute("layout") if node.hasAttribute("layout") else "flow") c.setLayout(layout) c.setOpaque(False) if node.getAttribute("opaque"): c.setOpaque(node.getAttribute("opaque")=="true") if node.getAttribute("background"): if(node.getAttribute("background")=="orange"): c.setBackground(Color.ORANGE) elif(node.getAttribute("background")=="green"): c.setBackground(Color.GREEN) for child in node.childNodes: if child.nodeName!="#text": if node.getAttribute("layout")=="gridbag": c.add(reloadComponent(game,dialog,child),getGridBagConstraints(game,child)) else: c.add(reloadComponent(game,dialog,child)) elif node.nodeName=="jlabel": c = JLabel(text,align) elif node.nodeName=="jbutton": c = JButton(text) if node.hasAttribute("enabled"): c.setEnabled(node.getAttribute("enabled")=="true"); elif node.nodeName=="settingspanel": c = SettingsPanel(game) for g in node.childNodes: if g.nodeName=="group": c.addGroup(int(g.getAttribute("id")),g.getAttribute("label")) for h in g.childNodes: if h.nodeName=="heading": c.addHeading(int(g.getAttribute("id")),h.getAttribute("label")) for s in h.childNodes: if s.nodeName=="setting": #<setting id="1" name="DISPLAY_REAL_WORLD_TIME" type="checkbox" label="Show Real-World Time"></setting> if s.getAttribute("items")!="": c.addSettingWithItems(int(g.getAttribute("id")),int(s.getAttribute("id")),s.getAttribute("label"),s.getAttribute("type"),s.getAttribute("items").split(",")) else: c.addSetting(int(g.getAttribute("id")),int(s.getAttribute("id")),s.getAttribute("label"),s.getAttribute("type")) c.finalizeSettingsPanel() dialog.registerSettingsPanel(int(node.getAttribute("id")),c) elif node.nodeName=="logspanel": c = LogsPanel(game) for g in node.childNodes: if g.nodeName=="group": c.addLog(int(g.getAttribute("id")),g.getAttribute("label")) c.finalizeLogsPanel() dialog.registerLogsPanel(int(node.getAttribute("id")),c) elif node.nodeName=="nglcanvas": c = NGLCanvas(game,int(getCascadingAttribute(game,node,"width")),int(getCascadingAttribute(game,node,"height"))) dialog.registerCanvas(int(node.getAttribute("id")),c) #Layout if node.parentNode.getAttribute("layout")=="absolute": c.setBounds(getBounds(game,node)) elif node.parentNode.getAttribute("layout")=="box-y": c.setAlignmentX(Component.CENTER_ALIGNMENT); if node.hasAttribute("width") and node.hasAttribute("height"): c.setPreferredSize(Dimension(int(getCascadingAttribute(game,node,"width")),int(getCascadingAttribute(game,node,"height")))) if node.hasAttribute("minWidth") and node.hasAttribute("minHeight"): c.setMinimumSize(Dimension(int(node.getAttribute("minWidth")),int(node.getAttribute("minHeight")))) if node.hasAttribute("maxWidth") and node.hasAttribute("maxHeight"): c.setMaximumSize(Dimension(int(node.getAttribute("maxWidth")),int(node.getAttribute("maxHeight")))) elif node.parentNode.getAttribute("layout")=="box-x": c.setAlignmentY(Component.CENTER_ALIGNMENT); if node.hasAttribute("width") and node.hasAttribute("height"): c.setPreferredSize(Dimension(int(getCascadingAttribute(game,node,"width")),int(getCascadingAttribute(game,node,"height")))) if node.hasAttribute("minWidth") and node.hasAttribute("minHeight"): c.setMinimumSize(Dimension(int(node.getAttribute("minWidth")),int(node.getAttribute("minHeight")))) if node.hasAttribute("maxWidth") and node.hasAttribute("maxHeight"): c.setMaximumSize(Dimension(int(node.getAttribute("maxWidth")),int(node.getAttribute("maxHeight")))) if node.nodeName!="nglcanvas" and node.nodeName!="jpanel" and node.nodeName!="settingspanel": addListeners(game,c,node) return c;
def __init__(self): #obtain prefixes from folder self.dict1 = self.obtain_prefixes( ) #Run prefix selection function - sets source directory, requests prefix size, outputs prefix dictionary lst = list(self.dict1.keys()) #pull prefixes only, as list self.lang = lst self.lst = JList(self.lang, valueChanged=self.listSelect ) # pass prefix list to GUI selection list # general GUI layout parameters, no data processing here self.frame = JFrame("Image Selection") self.frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) self.frame.setLocation(100, 100) self.frame.setSize(800, 350) self.frame.setLayout(BorderLayout()) self.frame.add(self.lst, BorderLayout.NORTH) self.lst.selectionMode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION self.button1 = JButton('Select item(s)', actionPerformed=self.clickhere) #Save option radio buttons and file extension selection #set main right panel (sub panels will fit within this) rightpanel = JPanel() rightpanel.setLayout(BoxLayout(rightpanel, BoxLayout.Y_AXIS)) #set up savestate panel buttonpanel = JPanel() self.radiobutton1 = JRadioButton( "Open selected 3D stacks and max projections \n and save max projections", True) self.radiobutton2 = JRadioButton( "Open selected 3D stacks and max projections \n and DO NOT save max projections" ) infoLabel = JLabel( "<html>Hold ctrl and click multiple prefixes to select multiple options. Will load stacks and MIPs separately <br><br> Type file extension in text field below:</html>", SwingConstants.LEFT) grp = ButtonGroup() grp.add(self.radiobutton1) grp.add(self.radiobutton2) #buttonpanel.setLayout(BoxLayout(buttonpanel, BoxLayout.Y_AXIS)) buttonpanel.add(Box.createVerticalGlue()) buttonpanel.add(infoLabel) buttonpanel.add(Box.createRigidArea(Dimension(0, 5))) buttonpanel.add(self.radiobutton1) buttonpanel.add(Box.createRigidArea(Dimension(0, 5))) buttonpanel.add(self.radiobutton2) #file extension instruction panel infopanel = JPanel() infopanel.setLayout(FlowLayout(FlowLayout.LEFT)) infopanel.setMaximumSize( infopanel.setPreferredSize(Dimension(650, 100))) infopanel.add(infoLabel) #file extension input inputPanel = JPanel() inputPanel.setLayout(BoxLayout(inputPanel, BoxLayout.X_AXIS)) self.filetype = JTextField(".tif", 15) self.filetype.setMaximumSize(self.filetype.getPreferredSize()) inputPanel.add(self.filetype) ########### WIP - integrate prefix selection with main pane, with dynamically updating prefix list ##infoLabel3 = JLabel("how long is the file prefix to group by?(integer value only)") ##self.prefix_init = JTextField() ##buttonpanel.add(infoLabel3) ##buttonpanel.add(self.prefix_init) ########### !WIP #add file extension and savestate panels to main panel rightpanel.add(infopanel) rightpanel.add(inputPanel) rightpanel.add(buttonpanel, BorderLayout.EAST) #split list and radiobutton pane (construct overall window) spl = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) spl.leftComponent = JScrollPane(self.lst) spl.setDividerLocation(150) spl.rightComponent = rightpanel self.frame.add(spl) self.frame.add(self.button1, BorderLayout.SOUTH) # GUI layout done, initialise GUI to select prefixes, file extension and save option self.frame.setVisible(True)
class Config(ITab): """Defines the Configuration tab""" def __init__(self, callbacks, parent): # Initialze self stuff self._callbacks = callbacks self.config = {} self.ext_stats = {} self.url_reqs = [] self.parse_files = False self.tab = JPanel(GridBagLayout()) self.view_port_text = JTextArea("===SpyDir===") self.delim = JTextField(30) self.ext_white_list = JTextField(30) # I'm not sure if these fields are necessary still # why not just use Burp func to handle this? # leaving them in case I need it for the HTTP handler later # self.cookies = JTextField(30) # self.headers = JTextField(30) self.url = JTextField(30) self.parent_window = parent self.plugins = {} self.loaded_p_list = set() self.loaded_plugins = False self.config['Plugin Folder'] = None self.double_click = False self.source_input = "" self.print_stats = True self.curr_conf = JLabel() self.window = JFrame("Select plugins", preferredSize=(200, 250), windowClosing=self.p_close) self.window.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE) self.window.setVisible(False) # Initialize local stuff tab_constraints = GridBagConstraints() status_field = JScrollPane(self.view_port_text) # Configure view port self.view_port_text.setEditable(False) labels = self.build_ui() # Add things to rows tab_constraints.anchor = GridBagConstraints.FIRST_LINE_END tab_constraints.gridx = 1 tab_constraints.gridy = 0 tab_constraints.fill = GridBagConstraints.HORIZONTAL self.tab.add(JButton( "Resize screen", actionPerformed=self.resize), tab_constraints) tab_constraints.gridx = 0 tab_constraints.gridy = 1 tab_constraints.anchor = GridBagConstraints.FIRST_LINE_START self.tab.add(labels, tab_constraints) tab_constraints.gridx = 1 tab_constraints.gridy = 1 tab_constraints.fill = GridBagConstraints.BOTH tab_constraints.weightx = 1.0 tab_constraints.weighty = 1.0 tab_constraints.anchor = GridBagConstraints.FIRST_LINE_END self.tab.add(status_field, tab_constraints) try: self._callbacks.customizeUiComponent(self.tab) except Exception: pass def build_ui(self): """Builds the configuration screen""" labels = JPanel(GridLayout(21, 1)) checkbox = JCheckBox("Attempt to parse files for URL patterns?", False, actionPerformed=self.set_parse) stats_box = JCheckBox("Show stats?", True, actionPerformed=self.set_show_stats) # The two year old in me is laughing heartily plug_butt = JButton("Specify plugins location", actionPerformed=self.set_plugin_loc) load_plug_butt = JButton("Select plugins", actionPerformed=self.p_build_ui) parse_butt = JButton("Parse directory", actionPerformed=self.parse) clear_butt = JButton("Clear text", actionPerformed=self.clear) spider_butt = JButton("Send to Spider", actionPerformed=self.scan) save_butt = JButton("Save config", actionPerformed=self.save) rest_butt = JButton("Restore config", actionPerformed=self.restore) source_butt = JButton("Input Source File/Directory", actionPerformed=self.get_source_input) # Build grid labels.add(source_butt) labels.add(self.curr_conf) labels.add(JLabel("String Delimiter:")) labels.add(self.delim) labels.add(JLabel("Extension Whitelist:")) labels.add(self.ext_white_list) labels.add(JLabel("URL:")) labels.add(self.url) # Leaving these here for now. # labels.add(JLabel("Cookies:")) # labels.add(self.cookies) # labels.add(JLabel("HTTP Headers:")) # labels.add(self.headers) labels.add(checkbox) labels.add(stats_box) labels.add(plug_butt) labels.add(parse_butt) labels.add(JButton("Show all endpoints", actionPerformed=self.print_endpoints)) labels.add(clear_butt) labels.add(spider_butt) labels.add(JLabel("")) labels.add(save_butt) labels.add(rest_butt) labels.add(load_plug_butt) # Tool tips! self.delim.setToolTipText("Use to manipulate the final URL. " "See About tab for example.") self.ext_white_list.setToolTipText("Define a comma delimited list of" " file extensions to parse. Use *" " to parse all files.") self.url.setToolTipText("Enter the target URL") checkbox.setToolTipText("Parse files line by line using plugins" " to enumerate language/framework specific" " endpoints") parse_butt.setToolTipText("Attempt to enumerate application endpoints") clear_butt.setToolTipText("Clear status window and the parse results") spider_butt.setToolTipText("Process discovered endpoints") save_butt.setToolTipText("Saves the current config settings") rest_butt.setToolTipText("<html>Restores previous config settings:" "<br/>-Input Directory<br/>-String Delim" "<br/>-Ext WL<br/>-URL<br/>-Plugins") source_butt.setToolTipText("Select the application's " "source directory or file to parse") return labels def set_url(self, menu_url): """Changes the configuration URL to the one from the menu event""" self.url.setText(menu_url) # Event functions def set_parse(self, event): """ Handles the click event from the UI checkbox to attempt code level parsing """ self.parse_files = not self.parse_files if self.parse_files: if not self.loaded_plugins: self._plugins_missing_warning() def restore(self, event): """Attempts to restore the previously saved configuration.""" jdump = None try: jdump = loads(self._callbacks.loadExtensionSetting("config")) except Exception as exc: # Generic exception thrown directly to user self.update_scroll( "[!!] Error during restore!\n\tException: %s" % str(exc)) if jdump is not None: self.url.setText(jdump.get('URL')) # self.cookies.setText(jdump.get('Cookies')) # self.headers.setText(jdump.get("Headers")) ewl = "" for ext in jdump.get('Extension Whitelist'): ewl += ext + ", " self.ext_white_list.setText(ewl[:-2]) self.delim.setText(jdump.get('String Delimiter')) self.source_input = jdump.get("Input Directory") self.config['Plugin Folder'] = jdump.get("Plugin Folder") if (self.config['Plugin Folder'] is not None and (len(self.plugins.values()) < 1)): self._load_plugins(self.config['Plugin Folder']) self._update() self.update_scroll("[^] Restore complete!") else: self.update_scroll("[!!] Restore failed!") def save(self, event=None): """ Saves the configuration details to a Burp Suite's persistent store. """ self._update() try: if not self._callbacks.isInScope(URL(self.url.getText())): self.update_scroll("[!!] URL provided is NOT in Burp Scope!") except MalformedURLException: # If url field is blank we'll pass # still save the settings. try: self._callbacks.saveExtensionSetting("config", dumps(self.config)) self.update_scroll("[^] Settings saved!") except Exception: self.update_scroll("[!!] Error saving settings to Burp Suite!") def parse(self, event): """ Handles the click event from the UI. Attempts to parse the given directory (and/or source files) for url endpoints Saves the items found within the url_reqs list """ self._update() file_set = set() fcount = 0 other_dirs = set() self.ext_stats = {} if self.loaded_plugins: self.update_scroll("[^] Attempting to parse files" + " for URL patterns. This might take a minute.") if path.isdir(self.source_input): for dirname, _, filenames in walk(self.source_input): for filename in filenames: fcount += 1 ext = path.splitext(filename)[1] count = self.ext_stats.get(ext, 0) + 1 filename = "%s/%s" % (dirname, filename) self.ext_stats.update({ext: count}) if self.parse_files: # i can haz threading? file_set.update(self._code_as_endpoints(filename, ext)) elif self._ext_test(ext): r_files, oths = self._files_as_endpoints(filename, ext) file_set.update(r_files) other_dirs.update(oths) elif path.isfile(self.source_input): ext = path.splitext(self.source_input)[1] file_set.update(self._code_as_endpoints(self.source_input, ext)) else: self.update_scroll("[!!] Input Directory is not valid!") if len(other_dirs) > 0: self.update_scroll("[*] Found files matching file extension in:\n") for other_dir in other_dirs: self.update_scroll(" " * 4 + "%s\n" % other_dir) for item in file_set: if item.startswith("http://") or item.startswith("https://"): proto = item.split("//")[0] + '//' item = item.replace(proto, "") self.url_reqs.append(proto + item.replace('//', '/')) self._print_parsed_status(fcount) return (other_dirs, self.url_reqs) def scan(self, event): """ handles the click event from the UI. Adds the given URL to the burp scope and sends the requests to the burp spider """ temp_url = self.url.getText() if not self._callbacks.isInScope(URL(temp_url)): if not self.double_click: self.update_scroll("[!!] URL is not in scope! Press Send to " "Spider again to add to scope and scan!") self.double_click = True return else: self._callbacks.sendToSpider(URL(temp_url)) self.update_scroll( "[^] Sending %d requests to Spider" % len(self.url_reqs)) for req in self.url_reqs: self._callbacks.sendToSpider(URL(req)) def clear(self, event): """Clears the viewport and the current parse exts""" self.view_port_text.setText("===SpyDir===") self.ext_stats = {} def print_endpoints(self, event): """Prints the discovered endpoints to the status window.""" req_str = "" if len(self.url_reqs) > 0: self.update_scroll("[*] Printing all discovered endpoints:") for req in self.url_reqs: req_str += " %s\n" % req else: req_str = "[!!] No endpoints discovered" self.update_scroll(req_str) def set_show_stats(self, event): """Modifies the show stats setting""" self.print_stats = not self.print_stats def get_source_input(self, event): """Sets the source dir/file for parsing""" source_chooser = JFileChooser() source_chooser.setFileSelectionMode( JFileChooser.FILES_AND_DIRECTORIES) source_chooser.showDialog(self.tab, "Choose Source Location") chosen_source = source_chooser.getSelectedFile() try: self.source_input = chosen_source.getAbsolutePath() except AttributeError: pass if self.source_input is not None: self.update_scroll("[*] Source location: %s" % self.source_input) self.curr_conf.setText(self.source_input) # Plugin functions def _parse_file(self, filename, file_url): """ Attempts to parse a file with the loaded plugins Returns set of endpoints """ file_set = set() with open(filename, 'r') as plug_in: lines = plug_in.readlines() ext = path.splitext(filename)[1].upper() if ext in self.plugins.keys(): for plug in self.plugins.get(ext): if plug.enabled: res = plug.run(lines) if len(res) > 0: for i in res: i = file_url + i file_set.add(i) elif ext == '.TXT' and self._ext_test(ext): for i in lines: i = file_url + i file_set.add(i.strip()) return file_set def set_plugin_loc(self, event): """Attempts to load plugins from a specified location""" if self.config['Plugin Folder'] is not None: choose_plugin_location = JFileChooser(self.config['Plugin Folder']) else: choose_plugin_location = JFileChooser() choose_plugin_location.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY) choose_plugin_location.showDialog(self.tab, "Choose Folder") chosen_folder = choose_plugin_location.getSelectedFile() self.config['Plugin Folder'] = chosen_folder.getAbsolutePath() self._load_plugins(self.config['Plugin Folder']) def _load_plugins(self, folder): """ Parses a local directory to get the plugins related to code level scanning """ report = "" if len(self.plugins.keys()) > 0: report = "[^] Plugins reloaded!" for _, _, filenames in walk(folder): for p_name in filenames: n_e = path.splitext(p_name) # n_e = name_extension if n_e[1] == ".py": f_loc = "%s/%s" % (folder, p_name) loaded_plug = self._validate_plugin(n_e[0], f_loc) if loaded_plug: self.loaded_p_list.add(loaded_plug) if not report.startswith("[^]"): report += "%s loaded\n" % loaded_plug.get_name() self._dictify(self.loaded_p_list) if len(self.plugins.keys()) > 0: self.loaded_plugins = True else: report = "[!!] Plugins load failure" self.loaded_plugins = False self.update_scroll(report) return report def _validate_plugin(self, p_name, f_loc): """ Attempts to verify the manditory plugin functions to prevent broken plugins from loading. Generates an error message if plugin does not contain an appropriate function. """ # Load the plugin try: plug = load_source(p_name, f_loc) except Exception as exc: # this needs to be generic. self.update_scroll( "[!!] Error loading: %s\n\tType:%s Error: %s" % (f_loc, type(exc), str(exc))) # Verify the plugin's functions funcs = dir(plug) err = [] if "get_name" not in funcs: err.append("get_name()") if "get_ext" not in funcs: err.append("get_ext()") if "run" not in funcs: err.append("run()") # Report errors & return if len(err) < 1: return Plugin(plug, True) else: for issue in err: self.update_scroll("[!!] %s is missing: %s func" % (p_name, issue)) return None def _dictify(self, plist): """Converts the list of loaded plugins (plist) into a dictionary""" for p in plist: exts = p.get_ext().upper() for ext in exts.split(","): prev_load = self.plugins.get(ext, []) prev_load.append(p) self.plugins[ext] = prev_load # Status window functions def _print_parsed_status(self, fcount): """Prints the parsed directory status information""" if self.parse_files and not self.loaded_plugins: self._plugins_missing_warning() if len(self.url_reqs) > 0: self.update_scroll("[*] Example URL: %s" % self.url_reqs[0]) if self.print_stats: report = (("[*] Found: %r files to be requested.\n\n" + "[*] Stats: \n " + "Found: %r files.\n") % (len(self.url_reqs), fcount)) if len(self.ext_stats) > 0: report += ("[*] Extensions found: %s" % str(dumps(self.ext_stats, sort_keys=True, indent=4))) else: report = ("[*] Found: %r files to be requested.\n" % len(self.url_reqs)) self.update_scroll(report) return report def _plugins_missing_warning(self): """Prints a warning message""" self.update_scroll("[!!] No plugins loaded!") def update_scroll(self, text): """Updates the view_port_text with the new information""" temp = self.view_port_text.getText().strip() if text not in temp or text[0:4] == "[!!]": self.view_port_text.setText("%s\n%s" % (temp, text)) elif not temp.endswith("[^] Status unchanged"): self.view_port_text.setText("%s\n[^] Status unchanged" % temp) # Internal functions def _code_as_endpoints(self, filename, ext): file_set = set() file_url = self.config.get("URL") if self.loaded_plugins: if self._ext_test(ext): file_set.update( self._parse_file(filename, file_url)) else: file_set.update( self._parse_file(filename, file_url)) return file_set def _files_as_endpoints(self, filename, ext): """Generates endpoints via files with the appropriate extension(s)""" file_url = self.config.get("URL") broken_splt = "" other_dirs = set() # directories outside of the String Delim. file_set = set() str_del = self.config.get("String Delimiter") if not str_del: self.update_scroll("[!!] No available String Delimiter!") return spl_str = filename.split(str_del) try: # Fix for index out of bounds exception while parsing # subfolders _not_ included by the split if len(spl_str) > 1: file_url += ((spl_str[1]) .replace('\\', '/')) else: broken_splt = filename.split(self.source_input)[1] other_dirs.add(broken_splt) except Exception as exc: # Generic exception thrown directly to user self.update_scroll("[!!] Error parsing: " + "%s\n\tException: %s" % (filename, str(exc))) if self._ext_test(ext): if file_url != self.config.get("URL"): file_set.add(file_url) else: other_dirs.discard(broken_splt) return file_set, other_dirs def _ext_test(self, ext): """Litmus test for extension whitelist""" val = False if len(self.config.get("Extension Whitelist")) > 0: val = (len(ext) > 0 and (ext.strip().upper() in self.config.get("Extension Whitelist"))) elif "*" in self.config.get("Extension Whitelist"): val = True return val def _update(self): """Updates internal data""" self.config["Input Directory"] = self.source_input self.config["String Delimiter"] = self.delim.getText() white_list_text = self.ext_white_list.getText() self.config["Extension Whitelist"] = white_list_text.upper().split(',') file_url = self.url.getText() if not file_url.endswith('/') and file_url != "": file_url += '/' self.config["URL"] = file_url # self.config["Cookies"] = self.cookies.getText() # self.config["Headers"] = self.headers.getText() del self.url_reqs[:] self.curr_conf.setText(self.source_input) # Window sizing functions def resize(self, event): """Resizes the window to better fit Burp""" if self.parent_window is not None: par_size = self.parent_window.getSize() par_size.setSize(par_size.getWidth() * .99, par_size.getHeight() * .9) self.tab.setPreferredSize(par_size) self.parent_window.validate() self.parent_window.switch_focus() def p_close(self, event): """ Handles the window close event. """ self.window.setVisible(False) self.window.dispose() def p_build_ui(self, event): """ Adds a list of checkboxes, one for each loaded plugin to the Selct plugins window """ if not self.loaded_p_list: self.update_scroll("[!!] No plugins loaded!") return scroll_pane = JScrollPane() scroll_pane.setPreferredSize(Dimension(200, 250)) check_frame = JPanel(GridBagLayout()) constraints = GridBagConstraints() constraints.fill = GridBagConstraints.HORIZONTAL constraints.gridy = 0 constraints.anchor = GridBagConstraints.FIRST_LINE_START for plug in self.loaded_p_list: check_frame.add(JCheckBox(plug.get_name(), plug.enabled, actionPerformed=self.update_box), constraints) constraints.gridy += 1 vport = JViewport() vport.setView(check_frame) scroll_pane.setViewport(vport) self.window.contentPane.add(scroll_pane) self.window.pack() self.window.setVisible(True) def update_box(self, event): """ Handles the check/uncheck event for the plugin's box. """ for plug in self.loaded_p_list: if plug.get_name() == event.getActionCommand(): plug.enabled = not plug.enabled if plug.enabled: self.update_scroll("[^] Enabled: %s" % event.getActionCommand()) else: self.update_scroll("[^] Disabled: %s" % event.getActionCommand()) # ITab required functions @staticmethod def getTabCaption(): """Returns the name of the Burp Suite Tab""" return "SpyDir" def getUiComponent(self): """Returns the UI component for the Burp Suite tab""" return self.tab
composite = Composite(shell, SWT.EMBEDDED | SWT.RESIZE) # TODO keep this resize listener? #composite.addControlListener(CleanResizeListener()) #cgd = GridData(SWT.FILL, SWT.FILL, True, True) cgd = GridData() cgd.widthHint = 100 #cgd.heightHint = 200 cgd.heightHint = 404 #504 composite.setLayoutData(cgd) frame = SWT_AWT.new_Frame(composite) # Do this instead if running without SWT #frame=JFrame(title="Cars", resizable=1,defaultCloseOperation=JFrame.EXIT_ON_CLOSE) #frame.setSize(200,300) panel = JPanel() panel.setPreferredSize(Dimension(250,190)) applet = delvAppletFromP5Applet(inSite, "ColorLegendWithDropdownView", "CarsLegend") panel.add(applet) layout = FlowLayout() frame.setLayout(layout) frame.add(panel) applet.init() while applet.defaultSize and not applet.finished: pass # TODO move some of following and some of above into DelvVis #data = dataFromP5Applet(applet, "InSiteData", "InSite") data = dataFromP5Applet(applet, "DelvCSVData", "P5Data") delv = delvFromP5Applet(applet, data)
class BottomPanel(JPanel): def __init__(self): self.holdPanel = JPanel() self.topPanel = JPanel() self.bottomPanel = JPanel() self.holdPanel.setBackground(Color.decode('#dddee6')) self.topPanel.setBackground(Color.decode('#dddee6')) self.bottomPanel.setBackground(Color.decode('#dddee6')) self.topPanel.setPreferredSize(Dimension(300, 30)) self.regBar = JProgressBar() self.gatePassBar = JProgressBar() self.regLabel = JLabel('Register : ') self.gatepassLabel = JLabel(' Gate Pass : '******'') self.gatePercentlabel = JLabel('') self.refreshButton = JButton('Refresh', actionPerformed=self.updateProgress) self.regBar.setMinimum(0) self.regBar.setMaximum(100) self.regBar.setStringPainted(True) self.gatePassBar.setMinimum(0) self.gatePassBar.setMaximum(100) self.gatePassBar.setStringPainted(True) self.setLayout(BorderLayout()) self.updateProgress(None) def updateProgress(self, e): progress = client.get_progress() regTotal = progress[0] regRecog = progress[1] gateTotal = progress[2] gateRecog = progress[3] regPercent = int((regRecog * 100) / regTotal) gatePercent = int((gateRecog * 100) / gateTotal) self.regBar.setValue(regPercent) self.gatePassBar.setValue(gatePercent) self.regBar.setString(str(regPercent) + '%') self.gatePassBar.setString(str(gatePercent) + '%') self.regPercentlabel.setText(str(regRecog) + '/' + str(regTotal)) self.gatePercentlabel.setText( str(gateRecog) + '/' + str(gateTotal) + ' ') if regPercent <= 30: regColor = Color.RED elif regPercent > 30 and regPercent < 50: regColor = Color.ORANGE elif regPercent >= 50 and regPercent <= 100: regColor = Color.GREEN if gatePercent <= 30: gateColor = Color.RED elif gatePercent > 30 and gatePercent < 50: gateColor = Color.ORANGE elif gatePercent >= 50 and gatePercent <= 100: gateColor = Color.GREEN self.regBar.setForeground(regColor) self.gatePassBar.setForeground(gateColor) self.holdPanel.add(self.regLabel) self.holdPanel.add(self.regBar) self.holdPanel.add(self.regPercentlabel) self.holdPanel.add(self.gatepassLabel) self.holdPanel.add(self.gatePassBar) self.holdPanel.add(self.gatePercentlabel) self.holdPanel.add(self.refreshButton) self.add(self.holdPanel, BorderLayout.CENTER) self.add(self.topPanel, BorderLayout.PAGE_START) self.add(self.bottomPanel, BorderLayout.PAGE_END) self.validate()
def __init__(self, view): JPanel.__init__(self) self.view = view self.background = Color.white self.config_panel_height = 60 mainPanel = JPanel(background=self.background, layout=BorderLayout()) mainPanel.border = self.RoundedBorder() configPanel = JPanel(background=self.background, visible=False) self.layout = BorderLayout() self.add(mainPanel, BorderLayout.NORTH) self.add(configPanel, BorderLayout.SOUTH) self.config_button = JButton(Icon.arrowdown, rolloverIcon=ShadedIcon.arrowdown, toolTipText='configure', actionPerformed=self.configure, borderPainted=False, focusPainted=False, contentAreaFilled=False) self.add(self.config_button) self.configPanel = configPanel self.slider = JSlider(0, 1, 0, background=self.background) self.slider.snapToTicks = True mainPanel.add(self.slider) self.slider.addChangeListener(self) self.min_time = JLabel(' 0.0000 ', opaque=True, background=self.background) self.max_time = JLabel(' 0.0000 ', opaque=True, background=self.background) self.left_panel = JPanel(background=self.background) self.left_panel.add(JButton(Icon.restart, rolloverIcon=ShadedIcon.restart, toolTipText='restart', actionPerformed=self.start, borderPainted=False, focusPainted=False, contentAreaFilled=False)) self.left_panel.add(self.min_time) self.left_panel.add(JButton(icon=Icon.start, rolloverIcon=ShadedIcon.start, toolTipText='jump to beginning', actionPerformed=lambda x: self.slider.setValue(self.slider.minimum), borderPainted=False, focusPainted=False, contentAreaFilled=False)) self.right_panel = JPanel(background=self.background) self.right_panel.add(JButton(icon=Icon.end, rolloverIcon=ShadedIcon.end, toolTipText='jump to end', actionPerformed=lambda x: self.slider.setValue(self.slider.maximum), borderPainted=False, focusPainted=False, contentAreaFilled=False)) self.right_panel.add(self.max_time) self.playpause_button = JButton(Icon.play, actionPerformed=self.pause, rolloverIcon=ShadedIcon.play, toolTipText='continue', borderPainted=False, focusPainted=False, contentAreaFilled=False) self.right_panel.add(self.playpause_button) mainPanel.add(self.left_panel, BorderLayout.WEST) mainPanel.add(self.right_panel, BorderLayout.EAST) pdf = JPanel(layout=BorderLayout(), opaque=False) pdf.add(JButton(Icon.pdf, rolloverIcon=ShadedIcon.pdf, toolTipText='save pdf', actionPerformed=self.save_pdf, borderPainted=False, focusPainted=False, contentAreaFilled=False)) pdf.add(JLabel('pdf', horizontalAlignment=javax.swing.SwingConstants.CENTER), BorderLayout.NORTH) pdf.maximumSize = pdf.preferredSize configPanel.add(pdf) self.data = JPanel(layout=BorderLayout(), opaque=False) self.data.add(JButton(Icon.data, rolloverIcon=ShadedIcon.data, toolTipText='examine data', actionPerformed=self.show_data, borderPainted=False, focusPainted=False, contentAreaFilled=False)) self.data.add(JLabel('data', horizontalAlignment=javax.swing.SwingConstants.CENTER), BorderLayout.NORTH) self.data.maximumSize = self.data.preferredSize configPanel.add(self.data) mode = JPanel(layout=BorderLayout(), opaque=False) cb = JComboBox(['default', 'rate', 'direct']) if self.view.network.mode in [SimulationMode.DEFAULT, SimulationMode.PRECISE]: cb.setSelectedIndex(0) elif self.view.network.mode in [SimulationMode.RATE]: cb.setSelectedIndex(1) elif self.view.network.mode in [SimulationMode.DIRECT, SimulationMode.APPROXIMATE]: cb.setSelectedIndex(2) cb.addActionListener(self) self.mode_combobox = cb mode.add(cb) mode.add(JLabel('mode'), BorderLayout.NORTH) mode.maximumSize = mode.preferredSize configPanel.add(mode) dt = JPanel(layout=BorderLayout(), opaque=False) cb = JComboBox(['0.001', '0.0005', '0.0002', '0.0001']) cb.setSelectedIndex(0) self.view.dt = float(cb.getSelectedItem()) cb.addActionListener(self) self.dt_combobox = cb dt.add(cb) dt.add(JLabel('time step'), BorderLayout.NORTH) dt.maximumSize = dt.preferredSize configPanel.add(dt) rate = JPanel(layout=BorderLayout(), opaque=False) self.rate_combobox = JComboBox(['fastest', '1x', '0.5x', '0.2x', '0.1x', '0.05x', '0.02x', '0.01x', '0.005x', '0.002x', '0.001x']) self.rate_combobox.setSelectedIndex(4) self.view.set_target_rate(self.rate_combobox.getSelectedItem()) self.rate_combobox.addActionListener(self) rate.add(self.rate_combobox) rate.add(JLabel('speed'), BorderLayout.NORTH) rate.maximumSize = rate.preferredSize configPanel.add(rate) spin1 = JPanel(layout=BorderLayout(), opaque=False) self.record_time_spinner = JSpinner(SpinnerNumberModel((self.view.timelog.tick_limit - 1) * self.view.dt, 0.1, 100, 1), stateChanged=self.tick_limit) spin1.add(self.record_time_spinner) spin1.add(JLabel('recording time'), BorderLayout.NORTH) spin1.maximumSize = spin1.preferredSize configPanel.add(spin1) spin2 = JPanel(layout=BorderLayout(), opaque=False) self.filter_spinner = JSpinner(SpinnerNumberModel(self.view.tau_filter, 0, 0.5, 0.01), stateChanged=self.tau_filter) spin2.add(self.filter_spinner) spin2.add(JLabel('filter'), BorderLayout.NORTH) spin2.maximumSize = spin2.preferredSize configPanel.add(spin2) spin3 = JPanel(layout=BorderLayout(), opaque=False) self.time_shown_spinner = JSpinner(SpinnerNumberModel(self.view.time_shown, 0.01, 50, 0.1), stateChanged=self.time_shown) spin3.add(self.time_shown_spinner) spin3.add(JLabel('time shown'), BorderLayout.NORTH) spin3.maximumSize = spin3.preferredSize configPanel.add(spin3) spin4 = JPanel(layout=BorderLayout(), opaque=False) self.freq_spinner = JSpinner(SpinnerNumberModel(1000.0/self.view.data_update_period, 1, 50, 1), stateChanged=self.update_frequency) spin4.add(self.freq_spinner) spin4.add(JLabel('freq (Hz)'), BorderLayout.NORTH) spin4.maximumSize = spin4.preferredSize configPanel.add(spin4) layout = JPanel(layout=BorderLayout(), opaque=False) layout.add(JButton(icon=Icon.save, rolloverIcon=ShadedIcon.save, actionPerformed=self.save, borderPainted=False, focusPainted=False, contentAreaFilled=False, margin=java.awt.Insets(0, 0, 0, 0), toolTipText='save layout'), BorderLayout.WEST) layout.add(JButton(icon=Icon.restore, rolloverIcon=ShadedIcon.restore, actionPerformed=self.restore, borderPainted=False, focusPainted=False, contentAreaFilled=False, margin=java.awt.Insets(0, 0, 0, 0), toolTipText='restore layout'), BorderLayout.EAST) layout.add(JLabel('layout', horizontalAlignment=javax.swing.SwingConstants.CENTER), BorderLayout.NORTH) layout.maximumSize = layout.preferredSize configPanel.add(layout) configPanel.setPreferredSize(java.awt.Dimension(20, self.config_panel_height)) configPanel.visible = False for c in [dt, rate, spin1, spin2, spin3]: c.border = javax.swing.border.EmptyBorder(0, 10, 0, 10)