class JTabTitle(JPanel, ActionListener): def __init__(self, ui, tabName): self._ui = ui self.jStatusBtn = JButton() #self.jStatusBtn.setMargin(Insets(2,0,2,0)) self.jStatusBtn = JCheckBox() self.jStatusBtn.setToolTipText(Strings.jStatusBtn_tooltip) self.jStatusBtn.setMargin(Insets(1, 5, 1, 5)) #enlarged clickable zone self.jStatusBtn.setBackground(Color.RED) #transparent background self.add(self.jStatusBtn) self.jStatusBtn.addActionListener(self) self.jLabel = JDoubleClickTextField(self, tabName) self.add(self.jLabel) self.setOpaque(False) def actionPerformed(self, event): #Check box was clicked if self.jStatusBtn == event.getSource(): if self.jStatusBtn.isSelected(): self._ui.initVars(self) pass #do nothing for now def setTabName(self, tabName): self.jLabel.setText(tabName) def getTabName(self): return self.jLabel.getText()
class EditSymbolAttr(JPanel): def __init__(self, sattr): self.attr = sattr self.cbox = JColorChooser(self.attr.color) self.sz_field = JTextField(str(self.attr.size)) szpanel = JPanel() szpanel.add(self.sz_field) szpanel.setBorder(BorderFactory.createTitledBorder("symbol size (integer)")) self.filled_box = JCheckBox("Filled ?:",self.attr.filled) self.shape_cbox = JComboBox(SymbolProps.sym_shape_map.keys()) self.shape_cbox.setSelectedItem(self.attr.shape) self.shape_cbox.setBorder(BorderFactory.createTitledBorder("Shape")) panel1 = JPanel() panel1.setLayout(BorderLayout()) panel1.add(szpanel,BorderLayout.NORTH) panel2 = JPanel() panel2.setLayout(GridLayout(1,2)) panel2.add(self.shape_cbox) panel2.add(self.filled_box) panel1.add(panel2,BorderLayout.SOUTH) self.setLayout(BorderLayout()) self.add(self.cbox,BorderLayout.CENTER) self.add(panel1,BorderLayout.SOUTH) def setAttribute(self,sattr): self.attr = sattr self.cbox.color = self.attr.color self.sz_field.text = str(self.attr.size) self.shape_cbox.setSelectedItem(self.attr.shape) def update(self): self.attr.color = self.cbox.getColor() self.attr.size = string.atoi(self.sz_field.getText()) self.attr.filled = self.filled_box.isSelected() self.attr.shape = self.shape_cbox.getSelectedItem() self.attr.sym = self.attr.createSymbol()
class EditCurveAttr(JPanel): def __init__(self, cattr): self.attr = cattr self.cbox = JColorChooser(self.attr.color) self.sym_panel = EditSymbolAttr(cattr.sym_prop) self.thickness_field = JTextField(str(cattr.thickness), 2) self.draw_symbol_box = JCheckBox("Draw Symbol?", cattr.draw_symbol) self.dps_field = JTextField(str(self.attr.data_per_symbol), 2) self.dash_box = JComboBox(CurveProps.DASH_TYPES.keys()) self.dash_box.setSelectedItem(self.attr.dash_type) self.dash_box.setBorder( BorderFactory.createTitledBorder("Dash type: (Only JDK2 & Slow!)")) tpanelx = JPanel() tpanelx.add(self.thickness_field) tpanelx.setBorder( BorderFactory.createTitledBorder("curve thickness (integer)")) tpanely = JPanel() tpanely.add(self.dps_field) tpanely.setBorder( BorderFactory.createTitledBorder("data per symbol(integer)")) tpanel = JPanel() tpanel.setLayout(GridLayout(2, 2)) tpanel.add(self.draw_symbol_box) tpanel.add(tpanelx) tpanel.add(tpanely) tpanel.add(self.dash_box) panel1 = JPanel() panel1.setLayout(BorderLayout()) panel1.add(self.cbox, BorderLayout.CENTER) panel1.add(tpanel, BorderLayout.SOUTH) panel2 = JPanel() panel2.setLayout(BorderLayout()) panel2.add(self.sym_panel, BorderLayout.CENTER) tp1 = JTabbedPane() tp1.addTab("Curve Attributes", panel1) tp1.addTab("Symbol Attributes", panel2) tp1.setSelectedComponent(panel1) self.setLayout(BorderLayout()) self.add(tp1, BorderLayout.CENTER) def setAttribute(self, cattr): self.attr = cattr self.cbox.color = self.attr.color self.sym_panel.setAttribute(cattr.sym_prop) self.thickness_field.text = str(cattr.thickness) self.dps_field.text = str(cattr.data_per_symbol) self.draw_symbol_box.setSelected(cattr.draw_symbol) self.dash_box.setSelectedItem(cattr.dash_type) def update(self): self.attr.color = self.cbox.getColor() self.attr.thickness = string.atoi(self.thickness_field.text) self.attr.data_per_symbol = string.atoi(self.dps_field.text) self.attr.draw_symbol = self.draw_symbol_box.isSelected() self.attr.dash_type = self.dash_box.getSelectedItem() #print 'Updating Self.draw_symbol',self.draw_symbol,self.attr self.sym_panel.update()
class EditCurveAttr(JPanel): def __init__(self, cattr): self.attr = cattr self.cbox = JColorChooser(self.attr.color) self.sym_panel = EditSymbolAttr(cattr.sym_prop) self.thickness_field = JTextField(str(cattr.thickness),2) self.draw_symbol_box = JCheckBox("Draw Symbol?",cattr.draw_symbol) self.dps_field = JTextField(str(self.attr.data_per_symbol),2) self.dash_box = JComboBox(CurveProps.DASH_TYPES.keys()) self.dash_box.setSelectedItem(self.attr.dash_type) self.dash_box.setBorder(BorderFactory.createTitledBorder("Dash type: (Only JDK2 & Slow!)")) tpanelx = JPanel() tpanelx.add(self.thickness_field) tpanelx.setBorder(BorderFactory.createTitledBorder("curve thickness (integer)")) tpanely = JPanel() tpanely.add(self.dps_field) tpanely.setBorder(BorderFactory.createTitledBorder("data per symbol(integer)")) tpanel = JPanel();tpanel.setLayout(GridLayout(2,2)); tpanel.add(self.draw_symbol_box); tpanel.add(tpanelx); tpanel.add(tpanely); tpanel.add(self.dash_box); panel1 = JPanel() panel1.setLayout(BorderLayout()) panel1.add(self.cbox,BorderLayout.CENTER) panel1.add(tpanel, BorderLayout.SOUTH) panel2 = JPanel() panel2.setLayout(BorderLayout()) panel2.add(self.sym_panel,BorderLayout.CENTER) tp1 = JTabbedPane() tp1.addTab("Curve Attributes",panel1) tp1.addTab("Symbol Attributes",panel2) tp1.setSelectedComponent(panel1) self.setLayout(BorderLayout()) self.add(tp1,BorderLayout.CENTER) def setAttribute(self,cattr): self.attr = cattr self.cbox.color = self.attr.color self.sym_panel.setAttribute(cattr.sym_prop) self.thickness_field.text = str(cattr.thickness) self.dps_field.text = str(cattr.data_per_symbol) self.draw_symbol_box.setSelected(cattr.draw_symbol) self.dash_box.setSelectedItem(cattr.dash_type) def update(self): self.attr.color = self.cbox.getColor() self.attr.thickness = string.atoi(self.thickness_field.text) self.attr.data_per_symbol = string.atoi(self.dps_field.text) self.attr.draw_symbol = self.draw_symbol_box.isSelected() self.attr.dash_type = self.dash_box.getSelectedItem() #print 'Updating Self.draw_symbol',self.draw_symbol,self.attr self.sym_panel.update()
class RunPanel(JPanel, java.lang.Runnable): def __init__(self,view): self.view=view self.layout=BorderLayout() self.run_sim=JCheckBox('generate more data',False) self.add(self.run_sim) self.thread=java.lang.Thread(self) self.thread.priority=java.lang.Thread.MIN_PRIORITY self.thread.start() def run(self): while True: if self.run_sim.isSelected(): name=self.view.stats.name params=self.view.selected_params() print params self.view.stats(**params).run(call_after=self.view.graph.update) else: time.sleep(0.1)
def changeDomainPopup(self, oldDomain, index): hostField = JTextField(25) checkbox = JCheckBox() domainPanel = JPanel(GridLayout(0,1)) domainPanel.add(JLabel("Request %s: Domain %s inaccessible. Enter new domain." % (str(index),oldDomain))) firstline = JPanel() firstline.add(JLabel("Host:")) firstline.add(hostField) domainPanel.add(firstline) secondline = JPanel() secondline.add(JLabel("Replace domain for all requests?")) secondline.add(checkbox) domainPanel.add(secondline) result = JOptionPane.showConfirmDialog( self._splitpane,domainPanel, "Domain Inaccessible", JOptionPane.OK_CANCEL_OPTION) cancelled = (result == JOptionPane.CANCEL_OPTION) if cancelled: return (False, None, False) return (True, hostField.getText(), checkbox.isSelected())
class EditSymbolAttr(JPanel): def __init__(self, sattr): self.attr = sattr self.cbox = JColorChooser(self.attr.color) self.sz_field = JTextField(str(self.attr.size)) szpanel = JPanel() szpanel.add(self.sz_field) szpanel.setBorder( BorderFactory.createTitledBorder("symbol size (integer)")) self.filled_box = JCheckBox("Filled ?:", self.attr.filled) self.shape_cbox = JComboBox(SymbolProps.sym_shape_map.keys()) self.shape_cbox.setSelectedItem(self.attr.shape) self.shape_cbox.setBorder(BorderFactory.createTitledBorder("Shape")) panel1 = JPanel() panel1.setLayout(BorderLayout()) panel1.add(szpanel, BorderLayout.NORTH) panel2 = JPanel() panel2.setLayout(GridLayout(1, 2)) panel2.add(self.shape_cbox) panel2.add(self.filled_box) panel1.add(panel2, BorderLayout.SOUTH) self.setLayout(BorderLayout()) self.add(self.cbox, BorderLayout.CENTER) self.add(panel1, BorderLayout.SOUTH) def setAttribute(self, sattr): self.attr = sattr self.cbox.color = self.attr.color self.sz_field.text = str(self.attr.size) self.shape_cbox.setSelectedItem(self.attr.shape) def update(self): self.attr.color = self.cbox.getColor() self.attr.size = string.atoi(self.sz_field.getText()) self.attr.filled = self.filled_box.isSelected() self.attr.shape = self.shape_cbox.getSelectedItem() self.attr.sym = self.attr.createSymbol()
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, IContextMenuFactory): def registerExtenderCallbacks(self, callbacks): # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("Autorize") # create the log and a lock on which to synchronize when adding log entries self._log = ArrayList() self._lock = Lock() self.intercept = 0 self.initInterceptionFilters() self.initEnforcementDetector() self.initExport() self.initConfigurationTab() self.initTabs() self.initCallbacks() print "Thank you for installing Autorize v0.9 extension" print "by Barak Tawily" return def initExport(self): # ## init enforcement detector tab # exportLType = JLabel("File Type:") exportLType.setBounds(10, 10, 100, 30) exportLES = JLabel("Enforcement Statuses:") exportLES.setBounds(10, 50, 160, 30) exportFileTypes = ["HTML"] self.exportType = JComboBox(exportFileTypes) self.exportType.setBounds(100, 10, 200, 30) exportES = [ "All Statuses", "Authorization bypass!", "Authorization enforced??? (please configure enforcement detector)", "Authorization enforced!" ] self.exportES = JComboBox(exportES) self.exportES.setBounds(100, 50, 200, 30) exportLES = JLabel("Statuses:") exportLES.setBounds(10, 50, 100, 30) self.exportButton = JButton("Export", actionPerformed=self.exportToHTML) self.exportButton.setBounds(390, 25, 100, 30) self.exportPnl = JPanel() self.exportPnl.setLayout(None) self.exportPnl.setBounds(0, 0, 1000, 1000) self.exportPnl.add(exportLType) self.exportPnl.add(self.exportType) self.exportPnl.add(exportLES) self.exportPnl.add(self.exportES) self.exportPnl.add(self.exportButton) def initEnforcementDetector(self): # ## init enforcement detector tab # self.EDFP = ArrayList() self.EDCT = ArrayList() EDLType = JLabel("Type:") EDLType.setBounds(10, 10, 140, 30) EDLContent = JLabel("Content:") EDLContent.setBounds(10, 50, 140, 30) EDLabelList = JLabel("Filter List:") EDLabelList.setBounds(10, 165, 140, 30) EDStrings = [ "Finger Print: (enforced message body contains)", "Content-Length: (constant Content-Length number of enforced response)" ] self.EDType = JComboBox(EDStrings) self.EDType.setBounds(80, 10, 430, 30) self.EDText = JTextArea("", 5, 30) self.EDText.setBounds(80, 50, 300, 110) self.EDModel = DefaultListModel() self.EDList = JList(self.EDModel) self.EDList.setBounds(80, 175, 300, 110) self.EDList.setBorder(LineBorder(Color.BLACK)) self.EDAdd = JButton("Add filter", actionPerformed=self.addEDFilter) self.EDAdd.setBounds(390, 85, 120, 30) self.EDDel = JButton("Remove filter", actionPerformed=self.delEDFilter) self.EDDel.setBounds(390, 210, 120, 30) self.EDPnl = JPanel() self.EDPnl.setLayout(None) self.EDPnl.setBounds(0, 0, 1000, 1000) self.EDPnl.add(EDLType) self.EDPnl.add(self.EDType) self.EDPnl.add(EDLContent) self.EDPnl.add(self.EDText) self.EDPnl.add(self.EDAdd) self.EDPnl.add(self.EDDel) self.EDPnl.add(EDLabelList) self.EDPnl.add(self.EDList) def initInterceptionFilters(self): # ## init interception filters tab # IFStrings = [ "URL Contains: ", "Scope items only: (Content is not required)" ] self.IFType = JComboBox(IFStrings) self.IFType.setBounds(80, 10, 430, 30) self.IFModel = DefaultListModel() self.IFList = JList(self.IFModel) self.IFList.setBounds(80, 175, 300, 110) self.IFList.setBorder(LineBorder(Color.BLACK)) self.IFText = JTextArea("", 5, 30) self.IFText.setBounds(80, 50, 300, 110) IFLType = JLabel("Type:") IFLType.setBounds(10, 10, 140, 30) IFLContent = JLabel("Content:") IFLContent.setBounds(10, 50, 140, 30) IFLabelList = JLabel("Filter List:") IFLabelList.setBounds(10, 165, 140, 30) self.IFAdd = JButton("Add filter", actionPerformed=self.addIFFilter) self.IFAdd.setBounds(390, 85, 120, 30) self.IFDel = JButton("Remove filter", actionPerformed=self.delIFFilter) self.IFDel.setBounds(390, 210, 120, 30) self.filtersPnl = JPanel() self.filtersPnl.setLayout(None) self.filtersPnl.setBounds(0, 0, 1000, 1000) self.filtersPnl.add(IFLType) self.filtersPnl.add(self.IFType) self.filtersPnl.add(IFLContent) self.filtersPnl.add(self.IFText) self.filtersPnl.add(self.IFAdd) self.filtersPnl.add(self.IFDel) self.filtersPnl.add(IFLabelList) self.filtersPnl.add(self.IFList) def initConfigurationTab(self): # ## init configuration tab # self.prevent304 = JCheckBox("Prevent 304 Not Modified status code") self.prevent304.setBounds(290, 25, 300, 30) self.ignore304 = JCheckBox("Ignore 304/204 status code responses") self.ignore304.setBounds(290, 5, 300, 30) self.ignore304.setSelected(True) self.autoScroll = JCheckBox("Auto Scroll") self.autoScroll.setBounds(290, 45, 140, 30) startLabel = JLabel("Authorization checks:") startLabel.setBounds(10, 10, 140, 30) self.startButton = JButton("Autorize is off", actionPerformed=self.startOrStop) self.startButton.setBounds(160, 10, 120, 30) self.startButton.setBackground(Color(255, 100, 91, 255)) self.clearButton = JButton("Clear List", actionPerformed=self.clearList) self.clearButton.setBounds(10, 40, 100, 30) self.replaceString = JTextArea("Cookie: Insert=injected; header=here;", 5, 30) self.replaceString.setWrapStyleWord(True) self.replaceString.setLineWrap(True) self.replaceString.setBounds(10, 80, 470, 180) self.filtersTabs = JTabbedPane() self.filtersTabs.addTab("Enforcement Detector", self.EDPnl) self.filtersTabs.addTab("Interception Filters", self.filtersPnl) self.filtersTabs.addTab("Export", self.exportPnl) self.filtersTabs.setBounds(0, 280, 2000, 700) self.pnl = JPanel() self.pnl.setBounds(0, 0, 1000, 1000) self.pnl.setLayout(None) self.pnl.add(self.startButton) self.pnl.add(self.clearButton) self.pnl.add(self.replaceString) self.pnl.add(startLabel) self.pnl.add(self.autoScroll) self.pnl.add(self.ignore304) self.pnl.add(self.prevent304) self.pnl.add(self.filtersTabs) def initTabs(self): # ## init autorize tabs # self.logTable = Table(self) self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._splitpane.setResizeWeight(1) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) self.scrollPane.getVerticalScrollBar().addAdjustmentListener( autoScrollListener(self)) copyURLitem = JMenuItem("Copy URL") copyURLitem.addActionListener(copySelectedURL(self)) self.menu = JPopupMenu("Popup") self.menu.add(copyURLitem) self.tabs = JTabbedPane() self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self._originalrequestViewer = self._callbacks.createMessageEditor( self, False) self._originalresponseViewer = self._callbacks.createMessageEditor( self, False) self.tabs.addTab("Modified Request", self._requestViewer.getComponent()) self.tabs.addTab("Modified Response", self._responseViewer.getComponent()) self.tabs.addTab("Original Request", self._originalrequestViewer.getComponent()) self.tabs.addTab("Original Response", self._originalresponseViewer.getComponent()) self.tabs.addTab("Configuration", self.pnl) self.tabs.setSelectedIndex(4) self._splitpane.setRightComponent(self.tabs) def initCallbacks(self): # ## init callbacks # # customize our UI components self._callbacks.customizeUiComponent(self._splitpane) self._callbacks.customizeUiComponent(self.logTable) self._callbacks.customizeUiComponent(self.scrollPane) self._callbacks.customizeUiComponent(self.tabs) self._callbacks.customizeUiComponent(self.filtersTabs) self._callbacks.registerContextMenuFactory(self) # add the custom tab to Burp's UI self._callbacks.addSuiteTab(self) # ## Events functions # def startOrStop(self, event): if self.startButton.getText() == "Autorize is off": self.startButton.setText("Autorize is on") self.startButton.setBackground(Color.GREEN) self.intercept = 1 self._callbacks.registerHttpListener(self) else: self.startButton.setText("Autorize is off") self.startButton.setBackground(Color(255, 100, 91, 255)) self.intercept = 0 self._callbacks.removeHttpListener(self) def addEDFilter(self, event): typeName = self.EDType.getSelectedItem().split(":")[0] self.EDModel.addElement(typeName + ": " + self.EDText.getText()) def delEDFilter(self, event): index = self.EDList.getSelectedIndex() if not index == -1: self.EDModel.remove(index) def addIFFilter(self, event): typeName = self.IFType.getSelectedItem().split(":")[0] self.IFModel.addElement(typeName + ": " + self.IFText.getText()) def delIFFilter(self, event): index = self.IFList.getSelectedIndex() if not index == -1: self.IFModel.remove(index) def clearList(self, event): self._lock.acquire() self._log = ArrayList() row = self._log.size() self.fireTableRowsInserted(row, row) self._lock.release() def exportToHTML(self, event): parentFrame = JFrame() fileChooser = JFileChooser() fileChooser.setSelectedFile(File("AutorizeReprort.html")) fileChooser.setDialogTitle("Save Autorize Report") userSelection = fileChooser.showSaveDialog(parentFrame) if userSelection == JFileChooser.APPROVE_OPTION: fileToSave = fileChooser.getSelectedFile() enforcementStatusFilter = self.exportES.getSelectedItem() htmlContent = """<html><title>Autorize Report by Barak Tawily</title> <style> .datagrid table { border-collapse: collapse; text-align: left; width: 100%; } .datagrid {font: normal 12px/150% Arial, Helvetica, sans-serif; background: #fff; overflow: hidden; border: 1px solid #006699; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .datagrid table td, .datagrid table th { padding: 3px 10px; } .datagrid table thead th {background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; color:#FFFFFF; font-size: 15px; font-weight: bold; border-left: 1px solid #0070A8; } .datagrid table thead th:first-child { border: none; }.datagrid table tbody td { color: #00496B; border-left: 1px solid #E1EEF4;font-size: 12px;font-weight: normal; }.datagrid table tbody .alt td { background: #E1EEF4; color: #00496B; }.datagrid table tbody td:first-child { border-left: none; }.datagrid table tbody tr:last-child td { border-bottom: none; }.datagrid table tfoot td div { border-top: 1px solid #006699;background: #E1EEF4;} .datagrid table tfoot td { padding: 0; font-size: 12px } .datagrid table tfoot td div{ padding: 2px; }.datagrid table tfoot td ul { margin: 0; padding:0; list-style: none; text-align: right; }.datagrid table tfoot li { display: inline; }.datagrid table tfoot li a { text-decoration: none; display: inline-block; padding: 2px 8px; margin: 1px;color: #FFFFFF;border: 1px solid #006699;-webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; }.datagrid table tfoot ul.active, .datagrid table tfoot ul a:hover { text-decoration: none;border-color: #006699; color: #FFFFFF; background: none; background-color:#00557F;}div.dhtmlx_window_active, div.dhx_modal_cover_dv { position: fixed !important; } table { width: 100%; table-layout: fixed; } td { border: 1px solid #35f; overflow: hidden; text-overflow: ellipsis; } td.a { width: 13%; white-space: nowrap; } td.b { width: 9%; word-wrap: break-word; } </style> <body> <h1>Autorize Report<h1> <div class="datagrid"><table> <thead><tr><th>URL</th><th>Authorization Enforcement Status</th></tr></thead> <tbody>""" for i in range(0, self._log.size()): color = "" if self._log.get( i )._enfocementStatus == "Authorization enforced??? (please configure enforcement detector)": color = "yellow" if self._log.get(i)._enfocementStatus == "Authorization bypass!": color = "red" if self._log.get(i)._enfocementStatus == "Authorization enforced!": color = "LawnGreen" if enforcementStatusFilter == "All Statuses": htmlContent += "<tr bgcolor=\"%s\"><td><a href=\"%s\">%s</a></td><td>%s</td></tr>" % ( color, self._log.get(i)._url, self._log.get(i)._url, self._log.get(i)._enfocementStatus) else: if enforcementStatusFilter == self._log.get( i)._enfocementStatus: htmlContent += "<tr bgcolor=\"%s\"><td><a href=\"%s\">%s</a></td><td>%s</td></tr>" % ( color, self._log.get(i)._url, self._log.get(i)._url, self._log.get(i)._enfocementStatus) htmlContent += "</tbody></table></div></body></html>" f = open(fileToSave.getAbsolutePath(), 'w') f.writelines(htmlContent) f.close() # # implement IContextMenuFactory # def createMenuItems(self, invocation): responses = invocation.getSelectedMessages() if responses > 0: ret = LinkedList() requestMenuItem = JMenuItem("Send request to Autorize") cookieMenuItem = JMenuItem("Send cookie to Autorize") requestMenuItem.addActionListener( handleMenuItems(self, responses[0], "request")) cookieMenuItem.addActionListener( handleMenuItems(self, responses[0], "cookie")) ret.add(requestMenuItem) ret.add(cookieMenuItem) return (ret) return null # # implement ITab # def getTabCaption(self): return "Autorize" def getUiComponent(self): return self._splitpane # # extend AbstractTableModel # def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 2 def getColumnName(self, columnIndex): if columnIndex == 0: return "URL" if columnIndex == 1: return "Authorization Enforcement Status" return "" def getValueAt(self, rowIndex, columnIndex): logEntry = self._log.get(rowIndex) if columnIndex == 0: return logEntry._url.toString() if columnIndex == 1: return logEntry._enfocementStatus return "" # # implement IMessageEditorController # this allows our request/response viewers to obtain details about the messages being displayed # def getHttpService(self): return self._currentlyDisplayedItem.getHttpService() def getRequest(self): return self._currentlyDisplayedItem.getRequest() def getResponse(self): return self._currentlyDisplayedItem.getResponse() # # implement IHttpListener # def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): if self.intercept == 1: if self.prevent304.isSelected(): if messageIsRequest: requestHeaders = list( self._helpers.analyzeRequest(messageInfo).getHeaders()) newHeaders = list() found = 0 for header in requestHeaders: if not "If-None-Match:" in header and not "If-Modified-Since:" in header: newHeaders.append(header) found = 1 if found == 1: requestInfo = self._helpers.analyzeRequest(messageInfo) bodyBytes = messageInfo.getRequest()[requestInfo. getBodyOffset():] bodyStr = self._helpers.bytesToString(bodyBytes) messageInfo.setRequest( self._helpers.buildHttpMessage( newHeaders, bodyStr)) if not messageIsRequest: if not self.replaceString.getText( ) in self._helpers.analyzeRequest(messageInfo).getHeaders(): if self.ignore304.isSelected(): firstHeader = self._helpers.analyzeResponse( messageInfo.getResponse()).getHeaders()[0] if "304" in firstHeader or "204" in firstHeader: return if self.IFList.getModel().getSize() == 0: self.checkAuthorization( messageInfo, self._helpers.analyzeResponse( messageInfo.getResponse()).getHeaders()) else: urlString = str( self._helpers.analyzeRequest(messageInfo).getUrl()) for i in range(0, self.IFList.getModel().getSize()): if self.IFList.getModel().getElementAt(i).split( ":")[0] == "Scope items only": currentURL = URL(urlString) if self._callbacks.isInScope(currentURL): self.checkAuthorization( messageInfo, self._helpers.analyzeResponse( messageInfo.getResponse()). getHeaders()) if self.IFList.getModel().getElementAt(i).split( ":")[0] == "URL Contains": if self.IFList.getModel().getElementAt( i)[14:] in urlString: self.checkAuthorization( messageInfo, self._helpers.analyzeResponse( messageInfo.getResponse()). getHeaders()) return def makeRequest(self, messageInfo, message): requestURL = self._helpers.analyzeRequest(messageInfo).getUrl() return self._callbacks.makeHttpRequest( self._helpers.buildHttpService( str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https"), message) def makeMessage(self, messageInfo, removeOrNot): requestInfo = self._helpers.analyzeRequest(messageInfo) headers = requestInfo.getHeaders() if removeOrNot: headers = list(headers) removeHeaders = ArrayList() removeHeaders.add(self.replaceString.getText() [0:self.replaceString.getText().index(":")]) for header in headers[:]: for removeHeader in removeHeaders: if removeHeader in header: headers.remove(header) headers.append(self.replaceString.getText()) msgBody = messageInfo.getRequest()[requestInfo.getBodyOffset():] return self._helpers.buildHttpMessage(headers, msgBody) def checkAuthorization(self, messageInfo, originalHeaders): message = self.makeMessage(messageInfo, True) requestResponse = self.makeRequest(messageInfo, message) analyzedResponse = self._helpers.analyzeResponse( requestResponse.getResponse()) oldStatusCode = originalHeaders[0] newStatusCode = analyzedResponse.getHeaders()[0] oldContentLen = self.getContentLength(originalHeaders) newContentLen = self.getContentLength(analyzedResponse.getHeaders()) impression = "" EDFilters = self.EDModel.toArray() if oldStatusCode == newStatusCode: if oldContentLen == newContentLen: impression = "Authorization bypass!" else: impression = "Authorization enforced??? (please configure enforcement detector)" for filter in EDFilters: if str(filter).startswith("Content-Length: "): if newContentLen == filter: impression = "Authorization enforced!" if str(filter).startswith("Finger Print: "): if filter[14:] in self._helpers.bytesToString( requestResponse.getResponse() [analyzedResponse.getBodyOffset():]): impression = "Authorization enforced!" else: impression = "Authorization enforced!" self._lock.acquire() row = self._log.size() self._log.add( LogEntry(self._callbacks.saveBuffersToTempFiles(requestResponse), self._helpers.analyzeRequest(requestResponse).getUrl(), messageInfo, impression)) # same requests not include again. self.fireTableRowsInserted(row, row) self._lock.release() def getContentLength(self, analyzedResponseHeaders): for header in analyzedResponseHeaders: if "Content-Length:" in header: return header return "null" def getCookieFromMessage(self, messageInfo): headers = list( self._helpers.analyzeRequest( messageInfo.getRequest()).getHeaders()) for header in headers: if "Cookie:" in header: return header return None
class FindView(JDialog): ''' Prompt user to choose some options to find and replace text in ATF area. ''' def __init__(self, controller): self.logger = logging.getLogger("NammuController") self.setAlwaysOnTop(True) self.controller = controller self.pane = self.getContentPane() # Get key bindings configuration from settings key_strokes = self.controller.config['find_keystrokes'] # Configure key bindings for undo/redo # First decide when key bindings can be triggered: condition = JComponent.WHEN_IN_FOCUSED_WINDOW # InputMap maps key strokes to actions in string format (e.g. 'undo') # ActionMap maps string actions (e.g. 'undo') with a custom # AbstractAction subclass. pane = self.getContentPane() for action, key in key_strokes.iteritems(): key_stroke = KeyStroke.getKeyStroke( getattr(KeyEvent, key), Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) pane.getInputMap(condition).put(key_stroke, action) pane.getActionMap().put(action, KeyStrokeAction(self, action)) def display(self): ''' Displays window. ''' self.build() self.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) self.setResizable(False) self.setTitle("Find/Replace") self.pack() self.setLocationRelativeTo(None) self.visible = 1 def build(self): layout = BoxLayout(self.getContentPane(), BoxLayout.Y_AXIS) self.setLayout(layout) # Create all necessary panels find_panel = self.build_find_row() replace_panel = self.build_replace_row() options_panel = self.build_options_row() buttons_panel = self.build_buttons_row() # replace_panel = self.build_find_panel() # Add panels to main JFrame self.add(find_panel) self.add(replace_panel) self.add(options_panel) self.add(buttons_panel) # self.add(self.build_find_replace_rows()) def build_find_replace_rows(self): labels = ("Find: ", "Replace: ") # Create and populate the panel. panel = JPanel() for label in labels: row_panel = JPanel(FlowLayout()) label = JLabel(label, JLabel.TRAILING) row_panel.add(label, FlowLayout.LEFT) textfield = JTextField(20) label.setLabelFor(textfield) row_panel.add(textfield, FlowLayout.RIGHT) panel.add(row_panel) return panel def build_find_row(self): ''' Builds the find row. ''' panel = JPanel(FlowLayout()) label = JLabel("Find: ") panel.add(label) self.find_field = JTextField(20, actionPerformed=self.find_next) label.setLabelFor(self.find_field) panel.add(self.find_field) return panel def build_replace_row(self): ''' Builds the replace row. ''' panel = JPanel(FlowLayout()) label = JLabel("Replace: ") panel.add(label) self.replace_field = JTextField(20, actionPerformed=self.find_next) label.setLabelFor(self.replace_field) panel.add(self.replace_field) return panel def build_options_row(self): ''' Builds the panel with ignore case, regex, etc. options. ''' panel = JPanel(FlowLayout()) self.ignore_case_box = JCheckBox('Ignore Case') self.regex_box = JCheckBox('Regular Expression') self.selection_box = JCheckBox('Selection only') panel.add(self.ignore_case_box) panel.add(self.regex_box) panel.add(self.selection_box) return panel def build_buttons_row(self): ''' Builds the buttons row. ''' panel = JPanel() layout = SpringLayout() panel.setLayout(layout) # Create necessary components and add them to panel. find_next_button = JButton('Find Next', actionPerformed=self.find_next) replace_one_button = JButton('Replace', actionPerformed=self.replace_one) replace_all_button = JButton('Replace All', actionPerformed=self.replace_all) done_button = JButton('Done', actionPerformed=self.done) panel.add(find_next_button) panel.add(replace_one_button) panel.add(replace_all_button) panel.add(done_button) # Set up constraints to tell panel how to position components. layout.putConstraint(SpringLayout.WEST, find_next_button, 15, SpringLayout.WEST, panel) layout.putConstraint(SpringLayout.NORTH, find_next_button, 15, SpringLayout.NORTH, panel) layout.putConstraint(SpringLayout.WEST, replace_one_button, 5, SpringLayout.EAST, find_next_button) layout.putConstraint(SpringLayout.NORTH, replace_one_button, 15, SpringLayout.NORTH, panel) layout.putConstraint(SpringLayout.WEST, replace_all_button, 5, SpringLayout.EAST, replace_one_button) layout.putConstraint(SpringLayout.NORTH, replace_all_button, 15, SpringLayout.NORTH, panel) layout.putConstraint(SpringLayout.WEST, done_button, 5, SpringLayout.EAST, replace_all_button) layout.putConstraint(SpringLayout.NORTH, done_button, 15, SpringLayout.NORTH, panel) layout.putConstraint(SpringLayout.EAST, panel, 15, SpringLayout.EAST, done_button) layout.putConstraint(SpringLayout.SOUTH, panel, 10, SpringLayout.SOUTH, done_button) # Add this to NewAtf JFrame return panel def find_next(self, event=None): self.controller.find_next(self.find_field.getText(), self.ignore_case_box.isSelected(), self.regex_box.isSelected(), self.selection_box.isSelected()) def replace_one(self, event=None): self.controller.replace_one(self.find_field.getText(), self.replace_field.getText(), self.ignore_case_box.isSelected(), self.regex_box.isSelected(), self.selection_box.isSelected()) def replace_all(self, event=None): self.controller.replace_all(self.find_field.getText(), self.replace_field.getText(), self.ignore_case_box.isSelected(), self.regex_box.isSelected(), self.selection_box.isSelected()) def done(self, event): ''' Reset list of matches and close window. ''' self.controller.matches = None self.controller.text = None self.controller.controller.find_controller = None self.controller.atfAreaController.restore_highlight() self.dispose()
class JTabbedPaneClass: #判断域名返回IP地址 def getIp(self, domain): domain = domain.split(":")[0] ipExpression = re.compile('^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') domainExpression = re.compile( "^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$" ) if ipExpression.match(domain): return domain elif domainExpression.match(domain): myAddr = socket.getaddrinfo(domain, 'http')[0][4][0] return myAddr else: return "domain error" #提取域名或IP信息 def getDomain1(self, theDomain): domain1 = theDomain.split(":")[0] return domain1 def __init__(self): frame = JFrame("S1riu5 Spy") frame.setSize(700, 690) frame.setLocationRelativeTo(None) frame.setLayout(BorderLayout()) tabPane = JTabbedPane(JTabbedPane.TOP) #第一个Tab用来做C段查询 eachIp = self.getIp(HOSTDOMAIN) iList = eachIp.split(".") theIP = iList[0] + "." + iList[1] + "." + iList[2] + ".1/24" panel1 = JPanel() label = JLabel("IP CIDR:") self.textfield1 = JTextField(theIP, 15) button = JButton("SCAN", actionPerformed=self.cNmapScan) self.textArea = JTextArea(40, 65) self.textArea.append("IP: " + eachIp) self.textArea.setLineWrap(True) #激活自动换行功能 self.textArea.setWrapStyleWord(True) # 激活断行不断字功能 panel1.add(label) panel1.add(self.textfield1) panel1.add(button) panel1.add(JScrollPane(self.textArea)) #设置自动滚动条 tabPane.addTab("C segment query ", panel1) #第二个Tab用来做子域名查询 theName = self.getDomain1(HOSTDOMAIN) self.textArea2 = JTextArea(40, 65) #self.textArea.append("IP: " + eachIp) self.textArea2.setLineWrap(True) #激活自动换行功能 self.textArea2.setWrapStyleWord(True) # 激活断行不断字功能 label2 = JLabel("Domain: ") self.textfield2 = JTextField(theName, 15) button2 = JButton("SCAN", actionPerformed=self.subDomain) self.panel2 = JPanel() self.panel2.add(label2) self.panel2.add(self.textfield2) self.panel2.add(button2) #self.panel2.add(scrollPane) self.panel2.add(JScrollPane(self.textArea2)) tabPane.addTab("subDomains", self.panel2) #第三个Tab用来做敏感文件扫描 self.tableData0 = [["1", "2"]] colNames2 = ('url', 'http code') dataModel3 = DefaultTableModel(self.tableData0, colNames2) self.table3 = JTable(dataModel3) ## label3 = JLabel("URL: ") self.textfield3 = JTextField(HOSTDOMAIN, 15) self.textArea3 = JTextArea(40, 65) #self.textArea.append("IP: " + eachIp) self.textArea3.setLineWrap(True) #激活自动换行功能 self.textArea3.setWrapStyleWord(True) # 激活断行不断字功能 a = 0 b = 0 self.label4 = JLabel(str(a) + "/" + str(b)) # self.chkbox1 = JCheckBox('ASP') self.chkbox2 = JCheckBox('ASPX') self.chkbox3 = JCheckBox('JSP') self.chkbox4 = JCheckBox('PHP') self.chkbox5 = JCheckBox('MDB') self.chkbox6 = JCheckBox('DIR') button3 = JButton("SCAN", actionPerformed=self.senFileScan) panel3 = JPanel() panel3.add(label3) panel3.add(self.textfield3) panel3.add(self.chkbox1) panel3.add(self.chkbox2) panel3.add(self.chkbox3) panel3.add(self.chkbox4) panel3.add(self.chkbox5) panel3.add(self.chkbox6) panel3.add(button3) panel3.add(self.label4) panel3.add(JScrollPane(self.textArea3)) # tabPane.addTab("Sebsitive File", panel3) # frame.add(tabPane) frame.setVisible(True) #用来在第一个TAB打印nmap信息 def setResult(self, text): self.textArea.append(text) #用来在第二个TAB打印获得信息 def setResult2(self, textId, textDomain, textIp): text = str( textId ) + "----------------" + textDomain + "----------------" + str( textIp) + os.linesep self.textArea2.append(text) #self.textArea2.append("----------------------------------------" + os.linesep) #用来在第三个TAB打印文件扫描的结果 def setResult3(self, theMess01): self.textArea3.append(theMess01) def setLabel(self, a, b): hg = str(a) + "/" + str(b) self.label4.setText(hg) #C段扫描的主引擎 def cNmapScan(self, event): self.textArea.setText("") #------------------------------------------------------------------------------- def ipRange(ipaddr): """ Creates a generator that iterates through all of the IP addresses. The range can be specified in multiple formats. "192.168.1.0-192.168.1.255" : beginning-end "192.168.1.0/24" : CIDR "192.168.1.*" : wildcard """ def ipaddr_to_binary(ipaddr): """ A useful routine to convert a ipaddr string into a 32 bit long integer """ # from Greg Jorgensens python mailing list message q = ipaddr.split('.') return reduce(lambda a, b: long(a) * 256 + long(b), q) #------------------------------------------------------------------------------- def binary_to_ipaddr(ipbinary): """ Convert a 32-bit long integer into an ipaddr dotted-quad string """ # This one is from Rikard Bosnjakovic return socket.inet_ntoa(struct.pack('!I', ipbinary)) def ipaddr_to_binary(ipaddr): """ A useful routine to convert a ipaddr string into a 32 bit long integer """ # from Greg Jorgensens python mailing list message q = ipaddr.split('.') return reduce(lambda a, b: long(a) * 256 + long(b), q) #------------------------------------------------------------------------------- def binary_to_ipaddr(ipbinary): """ Convert a 32-bit long integer into an ipaddr dotted-quad string """ # This one is from Rikard Bosnjakovic return socket.inet_ntoa(struct.pack('!I', ipbinary)) #------------------------------------------------------------------------------- def cidr_iprange(ipaddr, cidrmask): """ Creates a generator that iterated through all of the IP addresses in a range given in CIDR notation """ # Get all the binary one's mask = (long(2)**long(32 - long(cidrmask))) - 1 b = ipaddr_to_binary(ipaddr) e = ipaddr_to_binary(ipaddr) b = long(b & ~mask) e = long(e | mask) while (b <= e): yield binary_to_ipaddr(b) b = b + 1 #------------------------------------------------------------------------------- def wildcard_iprange(ipaddr): """ Creates a generator that iterates through all of the IP address in a range given with wild card notation """ beginning = [] end = [] tmp = ipaddr.split('.') for i in tmp: if i == '*': beginning.append("0") end.append("255") else: beginning.append(i) end.append(i) b = beginning[:] e = end[:] while int(b[0]) <= int(e[0]): while int(b[1]) <= int(e[1]): while int(b[2]) <= int(e[2]): while int(b[3]) <= int(e[3]): yield b[0] + '.' + b[1] + '.' + b[2] + '.' + b[ 3] b[3] = "%d" % (int(b[3]) + 1) b[2] = "%d" % (int(b[2]) + 1) b[3] = beginning[3] b[1] = "%d" % (int(b[1]) + 1) b[2] = beginning[2] b[0] = "%d" % (int(b[0]) + 1) b[1] = beginning[1] # Did we get the IP address in the span format? span_re = re.compile( r'''(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) # The beginning IP Address \s*-\s* (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) # The end IP Address ''', re.VERBOSE) res = span_re.match(ipaddr) if res: beginning = res.group(1) end = res.group(2) return span_iprange(beginning, end) # Did we get the IP address in the CIDR format? cidr_re = re.compile( r'''(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) # The IP Address /(\d{1,2}) # The mask ''', re.VERBOSE) res = cidr_re.match(ipaddr) if res: addr = res.group(1) cidrmask = res.group(2) return cidr_iprange(addr, cidrmask) # Did we get the IP address in the wildcard format? wild_re = re.compile( r'''(\d{1,3}|\*)\. (\d{1,3}|\*)\. (\d{1,3}|\*)\. (\d{1,3}|\*) # The IP Address ''', re.VERBOSE) res = wild_re.match(ipaddr) if res: return wildcard_iprange(ipaddr) return "The ip address given to ipaddr is improperly formatted" ipCidr = self.textfield1.getText() domainExpression = re.compile( "^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$" ) if domainExpression.match(ipCidr): JOptionPane.showMessageDialog(None, "You must enter IP", "s1riu5", JOptionPane.INFORMATION_MESSAGE) else: ipList = list(ipRange(ipCidr)) print len(ipList) if len(ipList) == 256: del ipList[0] del ipList[254] global NMAPPATH scan = ScanList(ipList, self, [NMAPPATH, "-Pn", "-sT", "-sV", "--open"]) scan.start() def subDomain(self, event): print self.textfield2.getText() b = subDomainThread(self.textfield2.getText(), self) b.start() def senFileScan(self, event): #print "Hello" urlListASP = ["/admin.asp"] urlListASPX = ["/admin.aspx"] urlListJSP = ["/admin.jsp"] urlListPHP = ["/admin.php"] urlListMDB = ["/admin.mdb"] urlListDIR = ["/admin/"] if self.chkbox1.isSelected(): domainTextObj1 = open("path/ASP.txt", "r") for each1 in domainTextObj1.readlines(): each1 = each1.strip() urlListASP.append(each1) domainTextObj1.close() if self.chkbox2.isSelected(): domainTextObj2 = open("path/ASPX.txt", "r") for each2 in domainTextObj2.readlines(): each2 = each2.strip() urlListASPX.append(each2) domainTextObj2.close() if self.chkbox3.isSelected(): domainTextObj3 = open("path/JSP.txt", "r") for each3 in domainTextObj3.readlines(): each3 = each3.strip() urlListJSP.append(each3) domainTextObj3.close() if self.chkbox4.isSelected(): domainTextObj4 = open("path/PHP.txt", "r") for each4 in domainTextObj4.readlines(): each4 = each4.strip() urlListPHP.append(each4) domainTextObj4.close() if self.chkbox5.isSelected(): domainTextObj5 = open("path/MDB.txt", "r") for each5 in domainTextObj5.readlines(): each5 = each5.strip() urlListMDB.append(each5) domainTextObj5.close() if self.chkbox6.isSelected(): domainTextObj6 = open("path/DIR.txt", "r") for each6 in domainTextObj6.readlines(): each6 = each6.strip() urlListDIR.append(each6) domainTextObj6.close() app = [] app = urlListASP + urlListASPX + urlListJSP + urlListPHP + urlListMDB + urlListDIR app1 = list(set(app)) theUrlText = self.textfield3.getText() #if str(theUrlText[0 : 7]) == "http://": # theUrlText = "http://" + theUrlText print len(app1) print len(app) #fileObj1 = eachFileScan(theUrlText, app) #fileObj1.start() ab = numControl(theUrlText, app1, self) ab.start()
class Mi_Extension(IHttpListener, IScannerCheck): def __init__(self, extender): self._callbacks = extender._callbacks self._helpers = extender._callbacks.getHelpers() self._callbacks.registerScannerCheck(self) # Creamos el contenedor de paneles. self.contenedor = JTabbedPane() # Campos del sub-tab 1 (mash up) self._tab1_nombre = JTextField() self._tab1_apellido = JTextField() self._tab1_FNacimiento = JTextField() self._tab1_mascota = JTextField() self._tab1_otro = JTextField() self._tab1_feedback_ta = JTextArea('This may take a while . . .') self._tab1_feedback_ta.setEditable(False) self._tab1_feedback_sp = JScrollPane(self._tab1_feedback_ta) self._tab1_minsize = JSlider(4, 16, 6) self._tab1_minsize.setMajorTickSpacing(1) self._tab1_minsize.setPaintLabels(True) self._tab1_maxsize = JSlider(4, 16, 10) self._tab1_maxsize.setMajorTickSpacing(1) self._tab1_maxsize.setPaintLabels(True) self._tab1_specialchars = JTextField('!,@,#,$,&,*') self._tab1_transformations = JCheckBox('1337 mode') self._tab1_firstcapital = JCheckBox('first capital letter') # Campos del sub-tab 2 (redirect) self._tab2_JTFa = JTextField() self._tab2_JTFaa = JTextField() self._tab2_JTFb = JTextField() self._tab2_JTFbb = JTextField() self._tab2_boton = JButton(' Redirect is Off ', actionPerformed=self.switch_redirect) self._tab2_boton.background = Color.lightGray self._tab2_encendido = False # Campos del sub-tab 3 (loader) self._tab3_urls_ta = JTextArea(15, 5) self._tab3_urls_sp = JScrollPane(self._tab3_urls_ta) # Campos del sub-tab 4 (headers) self._tab4_tabla_model = DefaultTableModel() self._tab4_headers_dict = {} # Campos del sub-tab 5 (reverse ip) self._tab5_target = JTextArea(15, 5) self._tab5_target_sp = JScrollPane(self._tab5_target) def create(self): # Estilo general para todas las sub-tab. gBC = GridBagConstraints() gBC.fill = GridBagConstraints.BOTH gBC.ipadx = 5 gBC.ipady = 5 gBC.insets = Insets(0, 5, 5, 5) gBC.weightx = 0.5 #gBC.weighty = 0.7 ####################################### ### Creamos la primera sub-tab. (MASHUP) ####################################### tab_1 = JPanel(GridBagLayout()) tab_1_jlabelAyuda = JLabel( '<html><i>•Tip: This Mashup receive one or more keywords in order to generate a list of possible passwords</i></html>' ) tab_1_jlabelAyuda.setFont(Font("Serif", 0, 12)) gBC.gridx = 0 gBC.gridy = 0 tab_1.add( JLabel('<html><font color=green><i>Income:</i></font></html>'), gBC) gBC.gridy = 1 tab_1.add(JLabel('<html><b>• Name:</b></html>'), gBC) gBC.gridy = 2 tab_1.add(self._tab1_nombre, gBC) gBC.gridy = 3 tab_1.add(JLabel('<html><b>• Surname:</b></html>'), gBC) gBC.gridy = 4 tab_1.add(self._tab1_apellido, gBC) gBC.gridy = 5 tab_1.add(JLabel('<html><b>• Birthdate: (DDMMYYYY)</b></html>'), gBC) gBC.gridy = 6 tab_1.add(self._tab1_FNacimiento, gBC) gBC.gridy = 7 tab_1.add(JLabel('<html><b>• Pet:</b></html>'), gBC) gBC.gridy = 8 tab_1.add(self._tab1_mascota, gBC) gBC.gridy = 9 tab_1.add(JLabel('<html><b>• Anyother:</b></html>'), gBC) gBC.gridy = 10 tab_1.add(self._tab1_otro, gBC) gBC.gridy = 11 tab_1.add(JLabel('<html><b>• Passwd Min Size:</b></html>'), gBC) gBC.gridy = 12 tab_1.add(self._tab1_minsize, gBC) gBC.gridy = 13 tab_1.add(JLabel('<html><b>• Passwd Max Size:</b></html>'), gBC) gBC.gridy = 14 tab_1.add(self._tab1_maxsize, gBC) gBC.gridy = 15 tab_1.add( JLabel( '<html><b>• Especial Chars: (comma separated)</b></html>' ), gBC) gBC.gridy = 16 tab_1.add(self._tab1_specialchars, gBC) gBC.gridy = 17 tab_1.add(self._tab1_transformations, gBC) gBC.gridy = 18 tab_1.add(self._tab1_firstcapital, gBC) gBC.gridy = 19 tab_1.add(JButton('Mashup!', actionPerformed=self.mashup), gBC) gBC.gridy = 20 gBC.gridwidth = 3 tab_1.add(JSeparator(), gBC) gBC.gridwidth = 1 gBC.gridy = 21 gBC.gridwidth = 3 tab_1.add(tab_1_jlabelAyuda, gBC) gBC.gridwidth = 1 gBC.gridx = 1 gBC.gridy = 0 gBC.gridheight = 20 gBC.weightx = 0 tab_1.add(JSeparator(SwingConstants.VERTICAL), gBC) gBC.gridheight = 1 gBC.weightx = 0.5 gBC.gridx = 2 gBC.gridy = 0 tab_1.add( JLabel('<html><font color=green><i>Outcome:</i></font></html>'), gBC) gBC.gridy = 1 gBC.gridwidth = 2 gBC.gridheight = 18 tab_1.add(self._tab1_feedback_sp, gBC) gBC.gridwidth = 1 gBC.gridheight = 1 gBC.gridy = 19 tab_1.add( JButton('Copy to clipboard!', actionPerformed=self.cpy_clipboard), gBC) ####################################### ### Creamos la segunda sub-tab. (REDIRECT) ####################################### tab_2 = JPanel(GridBagLayout()) tab_2_jlabelAyuda = JLabel( '<html><i>•Tip: This Redirect receive a pair of hosts x,y in order to redirect from x to y.</i></html>' ) tab_2_jlabelAyuda.setFont(Font("Serif", 0, 12)) gBC.gridx = 0 gBC.gridy = 0 tab_2.add( JLabel('<html><b>• From: (i.e. www.facebook.com)</b></html>'), gBC) gBC.gridx = 1 gBC.gridy = 0 tab_2.add(self._tab2_JTFa, gBC) gBC.gridx = 2 gBC.gridy = 0 tab_2.add( JLabel('<html><b>• To: (i.e. www.myhomepage.es)</b></html>'), gBC) gBC.gridx = 3 gBC.gridy = 0 tab_2.add(self._tab2_JTFaa, gBC) gBC.gridx = 0 gBC.gridy = 1 gBC.gridwidth = 4 tab_2.add(JSeparator(), gBC) gBC.gridwidth = 1 gBC.gridx = 0 gBC.gridy = 2 tab_2.add(JLabel('<html><b>• From:</b></html>'), gBC) gBC.gridx = 1 gBC.gridy = 2 tab_2.add(self._tab2_JTFb, gBC) gBC.gridx = 2 gBC.gridy = 2 tab_2.add(JLabel('<html><b>• To:</b></html>'), gBC) gBC.gridx = 3 gBC.gridy = 2 tab_2.add(self._tab2_JTFbb, gBC) gBC.gridx = 0 gBC.gridy = 3 gBC.gridwidth = 4 tab_2.add(self._tab2_boton, gBC) gBC.gridwidth = 1 gBC.gridx = 0 gBC.gridy = 4 gBC.gridwidth = 4 gBC.insets = Insets(100, 10, 5, 10) tab_2.add(JSeparator(), gBC) gBC.gridwidth = 1 gBC.insets = Insets(5, 10, 5, 10) gBC.gridx = 0 gBC.gridy = 5 gBC.gridwidth = 4 tab_2.add(tab_2_jlabelAyuda, gBC) gBC.gridwidth = 1 ####################################### ### Creamos la tercera sub-tab. (LOADER) ####################################### tab_3 = JPanel(GridBagLayout()) tab_3_jlabelAyuda = JLabel( '<html><i>•Tip: This Loader receive a list of Hosts or IPs that will be added to the Burp Scope.</i></html>' ) tab_3_jlabelAyuda.setFont(Font("Serif", 0, 12)) gBC.gridx = 0 gBC.gridy = 0 tab_3.add( JLabel( '<html><font color=green><i>List of targets: (i.e. http://www.mytargetweb.com)</i></font></html>' ), gBC) gBC.gridy = 1 gBC.gridheight = 10 gBC.weighty = 0.5 tab_3.add(self._tab3_urls_sp, gBC) gBC.gridheight = 1 gBC.weighty = 0 gBC.gridy = 11 tab_3.add( JButton('Load Into Target => Scope!', actionPerformed=self.loader), gBC) gBC.gridy = 12 gBC.gridwidth = 5 gBC.insets = Insets(100, 10, 5, 10) tab_3.add(JSeparator(), gBC) gBC.gridwidth = 1 gBC.insets = Insets(5, 10, 5, 10) gBC.gridy = 13 tab_3.add(tab_3_jlabelAyuda, gBC) ####################################### ### Creamos la cuarta sub-tab. (HEADERS) ####################################### tab_4_jlabelAyuda = JLabel( "<html><i>•Tip: This Headers records all unique headers that appear in every host, check out the security headers.</i></html>" ) tab_4_jlabelAyuda.setFont(Font("Serif", 0, 12)) tab_4_jLabelRecomendacion = JLabel( "<html>•<b>Server</b>: Don't give away much information.<br> •<b>Content-Security-Policy</b>: Protect your site from XSS attacks by whitelisting sources of approved content.<br> •<b>Strict-Transport-Security</b>: Enforce the browser to use HTTPS.<br> •<b>Public-Key-Pins</b>: Protect your site from MITM attacks.<br> •<b>X-Content-Type-Options</b>: the valid value is -> nosniff .<br> •<b>X-Frame-Options</b>: tells the browser whether you want to allow your site to be framed or not.<br> •<b>X-XSS-Protection</b>: the best value is -> 1; mode=block .</html>" ) tab_4_jLabelRecomendacion.setFont(Font("Dialog", 0, 13)) tab_4 = JPanel(GridBagLayout()) splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT) tab_4_top = JPanel(GridBagLayout()) tab_4_bottom = JPanel(GridBagLayout()) gBC_table = GridBagConstraints() gBC_table.fill = GridBagConstraints.BOTH gBC_table.ipadx = 5 gBC_table.ipady = 5 gBC_table.insets = Insets(5, 10, 5, 10) gBC_table.weightx = 1 gBC_table.weighty = 1 tabla_datos = [] tabla_headers = ('Severity', 'Header', 'Value', 'Host') self._tab4_tabla_model = DefaultTableModel(tabla_datos, tabla_headers) tabla_ej = JTable(self._tab4_tabla_model) tabla_example = JScrollPane(tabla_ej, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) gBC_table.gridx = 0 gBC_table.gridy = 0 gBC_table.gridheight = 5 tab_4_top.add(tabla_example, gBC_table) gBC_table.gridheight = 1 gBC_table.weightx = 0.5 gBC_table.weighty = 0 gBC_table.gridwidth = 2 gBC_table.gridx = 0 gBC_table.gridy = 0 tab_4_bottom.add(JSeparator(), gBC_table) gBC_table.gridy = 1 tab_4_bottom.add(tab_4_jlabelAyuda, gBC_table) gBC_table.gridy = 2 tab_4_bottom.add(tab_4_jLabelRecomendacion, gBC_table) splitpane.setTopComponent(tab_4_top) splitpane.setBottomComponent(tab_4_bottom) gBC_table.weightx = 1 gBC_table.weighty = 1 gBC_table.gridx = 0 gBC_table.gridy = 0 tab_4.add(splitpane, gBC_table) ####################################### ### Creamos la quinta sub-tab. (ACTIVE SCAN) ####################################### tab_5 = JPanel(GridBagLayout()) tab_5_jlabelAyuda = JLabel( '<html><i>•Tip: This Quick Scan receive a list of targets and launch an active scan.</i></html>' ) tab_5_jlabelAyuda.setFont(Font("Serif", 0, 12)) tab_5_jlabelWarning = JLabel( '<html><font color=red><i>•Warning: Active scanning generates large numbers of requests which are malicious in form and which may result in compromise of the application. You should use this scanning mode with caution, only with the explicit permission of the application owner. For more information, read the documentation of active scan, Burp Suite.</font></i></html>' ) tab_5_jlabelWarning.setFont(Font("Dialog", 0, 13)) gBC.gridx = 0 gBC.gridy = 0 tab_5.add( JLabel( '<html><font color=green><i>List of targets: (i.e. http://192.168.1.1/index.html)</i></font></html>' ), gBC) gBC.gridy = 1 gBC.gridheight = 8 gBC.weighty = 0.5 tab_5.add(self._tab5_target_sp, gBC) gBC.gridheight = 1 gBC.weighty = 0 gBC.gridy = 9 tab_5.add(JButton('Launch Scan!', actionPerformed=self.do_active_scan), gBC) gBC.gridy = 10 gBC.gridwidth = 5 gBC.insets = Insets(100, 10, 5, 10) tab_5.add(JSeparator(), gBC) gBC.gridwidth = 1 gBC.insets = Insets(5, 10, 5, 10) gBC.gridy = 11 tab_5.add(tab_5_jlabelAyuda, gBC) gBC.gridy = 12 tab_5.add(tab_5_jlabelWarning, gBC) ####################################### ### Creamos la ultima sub-tab. ####################################### tab_about = JPanel(GridBagLayout()) gBC_about = GridBagConstraints() gBC_about.fill = GridBagConstraints.HORIZONTAL gBC_about.ipadx = 5 gBC_about.ipady = 5 gBC_about.insets = Insets(5, 10, 5, 10) gBC_about.weightx = 1 gBC_about.weighty = 1 Jlabel1 = JLabel('<html><b>Plug-in L-Tools</b></html>') Jlabel1.setFont(Font("Dialog", 1, 18)) jlabel2 = JLabel( '<html>This Plug-in provides utilities for pentesters, researchers and developers, in order to support their work.</html>' ) jlabel3 = JLabel('<html><b>CC-BY 4.0, 2017. Gino Angles</b></html>') jlabel3.setFont(Font("Dialog", 1, 14)) jlabel4 = JLabel('<html><b>License</b></html>') jlabel4.setFont(Font("Dialog", 1, 14)) jlabel5 = JLabel( '<html><img alt="Licensed under a Creative Commons BY" style="border-width:0" src="https://licensebuttons.net/l/by/4.0/88x31.png"></html>' ) jlabel6 = JLabel( '<html>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.</html>' ) jlabel7 = JLabel('<html><b>Dependencies</b></html>') jlabel7.setFont(Font("Dialog", 1, 14)) jlabel8 = JLabel('Jython +2.7') jlabel9 = JLabel('http://www.jython.org') gBC_about.gridx = 0 gBC_about.gridy = 0 tab_about.add(Jlabel1, gBC_about) gBC_about.gridy = 1 tab_about.add(jlabel2, gBC_about) gBC_about.gridy = 2 tab_about.add(jlabel3, gBC_about) gBC_about.gridy = 3 gBC_about.gridwidth = 5 tab_about.add(JSeparator(), gBC_about) gBC_about.gridwidth = 1 gBC_about.gridy = 4 tab_about.add(jlabel4, gBC_about) gBC_about.gridy = 5 tab_about.add(jlabel5, gBC_about) gBC_about.gridy = 6 tab_about.add(jlabel6, gBC_about) gBC_about.gridy = 7 gBC_about.gridwidth = 5 tab_about.add(JSeparator(), gBC_about) gBC_about.gridwidth = 1 gBC_about.gridy = 8 tab_about.add(jlabel7, gBC_about) gBC_about.gridy = 9 tab_about.add(jlabel8, gBC_about) gBC_about.gridy = 10 tab_about.add(jlabel9, gBC_about) # Añadimos los sub-tab al contenedor y lo devolvemos. self.contenedor.addTab('Mashup', tab_1) self.contenedor.addTab('Redirect', tab_2) self.contenedor.addTab('Loader', tab_3) self.contenedor.addTab('Headers', tab_4) self.contenedor.addTab('Quick Scan', tab_5) self.contenedor.addTab('About', tab_about) return self.contenedor # Funcion que copia el contenido de texto al clipboard. def cpy_clipboard(self, event): toolkit = Toolkit.getDefaultToolkit() clipboard = toolkit.getSystemClipboard() clipboard.setContents(StringSelection(self._tab1_feedback_ta.text), None) JOptionPane.showMessageDialog(self.contenedor, "Output copied to clipboard", "Information", JOptionPane.INFORMATION_MESSAGE) return # Funcion que instancia la clase Masher() y hace el mashup del sub-tab1 (mashup). def mashup(self, event): if self._tab1_minsize.value > self._tab1_maxsize.value: self._callbacks.issueAlert( 'Mashup=> min size have to be bigger than max size.') else: estado_JCH_trans = self._tab1_transformations.isSelected() especial_chars = self._tab1_specialchars.text.split(",") mymash = Masher(self._tab1_minsize.value, self._tab1_maxsize.value, especial_chars, estado_JCH_trans) reverse_name = self._tab1_nombre.text[::-1] if self._tab1_firstcapital.isSelected(): lista_palabras = [ self._tab1_nombre.text.title(), self._tab1_apellido.text.title(), self._tab1_FNacimiento.text, self._tab1_mascota.text.title(), self._tab1_otro.text.title(), reverse_name.title() ] else: lista_palabras = [ self._tab1_nombre.text, self._tab1_apellido.text, self._tab1_FNacimiento.text, self._tab1_mascota.text, self._tab1_otro.text, reverse_name ] while "" in lista_palabras: lista_palabras.remove("") rdo_rdo = mymash.mashup(lista_palabras, self._tab1_FNacimiento.text) self._tab1_feedback_ta.text = "\n".join(rdo_rdo) return # Funcion que activa/desactiva el redirect. def switch_redirect(self, event): if not self._tab2_encendido: self._tab2_boton.text = ' Redirect is On ' self._tab2_boton.background = Color.gray self._tab2_encendido = True # Registramos la instancia del escuchador http. self._callbacks.registerHttpListener(self) else: self._tab2_boton.text = ' Redirect is Off ' self._tab2_boton.background = Color.lightGray self._tab2_encendido = False # Borramos la instancia del escuchador http. self._callbacks.removeHttpListener(self) return # @override def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): if messageIsRequest and self._tab2_encendido: serviceHttp = messageInfo.getHttpService() if messageInfo.getHttpService().getHost() == self._tab2_JTFa.text: if self._tab2_JTFaa.text == '': self._tab2_JTFaa.text = 'localhost' messageInfo.setHttpService( self._helpers.buildHttpService(self._tab2_JTFaa.text, serviceHttp.getPort(), serviceHttp.getProtocol())) elif messageInfo.getHttpService().getHost( ) == self._tab2_JTFb.text: if self._tab2_JTFbb.text == '': self._tab2_JTFbb.text = 'localhost' messageInfo.setHttpService( self._helpers.buildHttpService(self._tab2_JTFbb.text, serviceHttp.getPort(), serviceHttp.getProtocol())) return # Funcion que carga el textArea de URL a Scope. def loader(self, event): lista_url = self._tab3_urls_ta.text.split("\n") for newUrl in lista_url: self._callbacks.includeInScope(URL(newUrl)) return # @override def doPassiveScan(self, request_response): _response = request_response.getResponse() _request = request_response.getRequest() _httpService = request_response.getHttpService() _url = request_response.getHttpService().getHost() info_response = self._helpers.analyzeResponse(_response) info_request = self._helpers.analyzeRequest(_httpService, _request) headers = info_response.getHeaders() _fullUrl = info_request.getUrl().toString() for head in headers: head_w1 = head.split("\n") for head_w2 in head_w1: head_w3 = head_w2.split(":") if len(head_w3) > 1: head_w3[0].encode('ascii', 'ignore') head_w3[1].encode('ascii', 'ignore') key = "%s-%s" % (_url, head_w3[0]) if key not in self._tab4_headers_dict: critical = self.analizeHeader(head_w3[0]) fila_tabla = [ critical, head_w3[0], head_w3[1], _fullUrl ] self._tab4_headers_dict[key] = fila_tabla self._tab4_tabla_model.addRow(fila_tabla) return # devuelve cuan importante es la cabecera HTTP. def analizeHeader(self, header): if header == "Content-Security-Policy": return "High" elif header == "X-Content-Type-Options": return "High" elif header == "X-Frame-Options": return "High" elif header == "X-XSS-Protection": return "High" elif header == "Strict-Transport-Security": return "High" elif header == "Public-Key-Pins": return "High" elif header == "Access-Control-Allow-Origin": return "High" elif header == "X-Permitted-Cross-Domain-Policies": return "High" elif header == "X-Powered-By": return "Information" elif header == "Server": return "Information" elif header == "Referrer-Policy": return "Medium" else: return " " # realiza un escaner al host/s apuntado. def do_active_scan(self, event): _lista_urls = self._tab5_target.text.split("\n") for _x_url in _lista_urls: _target_url = URL(_x_url) _target_request = self._helpers.buildHttpRequest(_target_url) _host = _target_url.getHost() _port = _target_url.getDefaultPort() _isHttps = True if _target_url.getProtocol() == "https" else False try: self._callbacks.doActiveScan(_host, _port, _isHttps, _target_request) except: pass return
class BurpExtender(IBurpExtender, ITab, IMessageEditorController, AbstractTableModel, IContextMenuFactory): def registerExtenderCallbacks(self, callbacks): # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("PT Vulnerabilities Manager") self.config = SafeConfigParser() self.createSection('projects') self.createSection('general') self.config.read('config.ini') self.chooser = JFileChooser() # create the log and a lock on which to synchronize when adding log entries self._log = ArrayList() self._lock = Lock() self.logTable = Table(self) self.logTable.getColumnModel().getColumn(0).setMaxWidth(35) self.logTable.getColumnModel().getColumn(1).setMinWidth(100) self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self.initVulnerabilityTab() self.initProjSettingsTab() self.initTabs() self.initCallbacks() if self.projPath.getText() != None: self.loadVulnerabilities(self.projPath.getText()) print "Thank you for installing PT Vulnerabilities Manager v1.0 extension" print "by Barak Tawily\n\n\n" print "Disclaimer:\nThis extension might create folders and files in your hardisk which might be declared as sensitive information, make sure you are creating projects under encrypted partition" return def initVulnerabilityTab(self): # ## init vulnerability tab # nameLabel = JLabel("Vulnerability Name:") nameLabel.setBounds(10, 10, 140, 30) self.addButton = JButton("Add",actionPerformed=self.addVuln) self.addButton.setBounds(10, 500, 100, 30) rmVulnButton = JButton("Remove",actionPerformed=self.rmVuln) rmVulnButton.setBounds(465, 500, 100, 30) mitigationLabel = JLabel("Mitigation:") mitigationLabel.setBounds(10, 290, 150, 30) addSSBtn = JButton("Add SS",actionPerformed=self.addSS) addSSBtn.setBounds(750, 40, 110, 30) deleteSSBtn = JButton("Remove SS",actionPerformed=self.removeSS) deleteSSBtn.setBounds(750, 75, 110, 30) piclistLabel = JLabel("Images list:") piclistLabel.setBounds(580, 10, 140, 30) self.screenshotsList = DefaultListModel() self.ssList = JList(self.screenshotsList) self.ssList.setBounds(580, 40, 150, 250) self.ssList.addListSelectionListener(ssChangedHandler(self)) self.ssList.setBorder(BorderFactory.createLineBorder(Color.GRAY)) previewPicLabel = JLabel("Selected image preview: (click to open in image viewer)") previewPicLabel.setBounds(580, 290, 500, 30) copyImgMenu = JMenuItem("Copy") copyImgMenu.addActionListener(copyImg(self)) self.imgMenu = JPopupMenu("Popup") self.imgMenu.add(copyImgMenu) self.firstPic = JLabel() self.firstPic.setBorder(BorderFactory.createLineBorder(Color.GRAY)) self.firstPic.setBounds(580, 320, 550, 400) self.firstPic.addMouseListener(imageClicked(self)) self.vulnName = JTextField("") self.vulnName.getDocument().addDocumentListener(vulnTextChanged(self)) self.vulnName.setBounds(140, 10, 422, 30) sevirities = ["Unclassified", "Critical","High","Medium","Low"] self.threatLevel = JComboBox(sevirities); self.threatLevel.setBounds(140, 45, 140, 30) colors = ["Color:", "Green", "Red"] self.colorCombo = JComboBox(colors); self.colorCombo.setBounds(465, 45, 100, 30) self.colorCombo severityLabel = JLabel("Threat Level:") severityLabel.setBounds(10, 45, 100, 30) descriptionLabel = JLabel("Description:") descriptionLabel.setBounds(10, 80, 100, 30) self.descriptionString = JTextArea("", 5, 30) self.descriptionString.setWrapStyleWord(True); self.descriptionString.setLineWrap(True) self.descriptionString.setBounds(10, 110, 555, 175) descriptionStringScroll = JScrollPane(self.descriptionString) descriptionStringScroll.setBounds(10, 110, 555, 175) descriptionStringScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED) self.mitigationStr = JTextArea("", 5, 30) self.mitigationStr.setWrapStyleWord(True); self.mitigationStr.setLineWrap(True) self.mitigationStr.setBounds(10, 320, 555, 175) mitigationStrScroll = JScrollPane(self.mitigationStr) mitigationStrScroll.setBounds(10, 320, 555, 175) mitigationStrScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED) self.pnl = JPanel() self.pnl.setBounds(0, 0, 1000, 1000); self.pnl.setLayout(None); self.pnl.add(addSSBtn) self.pnl.add(piclistLabel) self.pnl.add(nameLabel) self.pnl.add(deleteSSBtn) self.pnl.add(rmVulnButton) self.pnl.add(severityLabel) self.pnl.add(mitigationLabel) self.pnl.add(descriptionLabel) self.pnl.add(previewPicLabel) self.pnl.add(mitigationStrScroll) self.pnl.add(descriptionStringScroll) self.pnl.add(self.ssList) self.pnl.add(self.firstPic) self.pnl.add(self.addButton) self.pnl.add(self.vulnName) self.pnl.add(self.threatLevel) self.pnl.add(self.colorCombo) def initProjSettingsTab(self): # init project settings projNameLabel = JLabel("Name:") projNameLabel.setBounds(10, 50, 140, 30) self.projName = JTextField("") self.projName.setBounds(140, 50, 320, 30) self.projName.getDocument().addDocumentListener(projTextChanged(self)) detailsLabel = JLabel("Details:") detailsLabel.setBounds(10, 120, 140, 30) reportLabel = JLabel("Generate Report:") reportLabel.setBounds(10, 375, 140, 30) types = ["DOCX","HTML","XLSX"] self.reportType = JComboBox(types) self.reportType.setBounds(10, 400, 140, 30) generateReportButton = JButton("Generate", actionPerformed=self.generateReport) generateReportButton.setBounds(160, 400, 90, 30) self.projDetails = JTextArea("", 5, 30) self.projDetails.setWrapStyleWord(True); self.projDetails.setLineWrap(True) projDetailsScroll = JScrollPane(self.projDetails) projDetailsScroll.setBounds(10, 150, 450, 175) projDetailsScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED) projPathLabel = JLabel("Path:") projPathLabel.setBounds(10, 90, 140, 30) self.projPath = JTextField("") self.projPath.setBounds(140, 90, 320, 30) chooseProjPathButton = JButton("Browse...",actionPerformed=self.chooseProjPath) chooseProjPathButton.setBounds(470, 90, 100, 30) importProjButton = JButton("Import",actionPerformed=self.importProj) importProjButton.setBounds(470, 10, 100, 30) exportProjButton = JButton("Export",actionPerformed=self.exportProj) exportProjButton.setBounds(575, 10, 100, 30) openProjButton = JButton("Open Directory",actionPerformed=self.openProj) openProjButton.setBounds(680, 10, 130, 30) currentProjectLabel = JLabel("Current:") currentProjectLabel.setBounds(10, 10, 140, 30) projects = self.config.options('projects') self.currentProject = JComboBox(projects) self.currentProject.addActionListener(projectChangeHandler(self)) self.currentProject.setBounds(140, 10, 140, 30) self.autoSave = JCheckBox("Auto Save Mode") self.autoSave.setEnabled(False) # implement this feature self.autoSave.setBounds(300, 10, 140, 30) self.autoSave.setToolTipText("Will save any changed value while focus is out") addProjButton = JButton("Add / Update",actionPerformed=self.addProj) addProjButton.setBounds(10, 330, 150, 30) removeProjButton = JButton("Remove Current",actionPerformed=self.rmProj) removeProjButton.setBounds(315, 330, 146, 30) generalOptions = self.config.options('general') if 'default project' in generalOptions: defaultProj = self.config.get('general','default project') self.currentProject.getModel().setSelectedItem(defaultProj) self.projPath.setText(self.config.get('projects',self.currentProject.getSelectedItem())) self.clearProjTab = True self.projectSettings = JPanel() self.projectSettings.setBounds(0, 0, 1000, 1000) self.projectSettings.setLayout(None) self.projectSettings.add(reportLabel) self.projectSettings.add(detailsLabel) self.projectSettings.add(projPathLabel) self.projectSettings.add(addProjButton) self.projectSettings.add(openProjButton) self.projectSettings.add(projNameLabel) self.projectSettings.add(projDetailsScroll) self.projectSettings.add(importProjButton) self.projectSettings.add(exportProjButton) self.projectSettings.add(removeProjButton) self.projectSettings.add(generateReportButton) self.projectSettings.add(chooseProjPathButton) self.projectSettings.add(currentProjectLabel) self.projectSettings.add(self.projPath) self.projectSettings.add(self.autoSave) self.projectSettings.add(self.projName) self.projectSettings.add(self.reportType) self.projectSettings.add(self.currentProject) def initTabs(self): # ## init autorize tabs # self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) colorsMenu = JMenu("Paint") redMenu = JMenuItem("Red") noneMenu = JMenuItem("None") greenMenu = JMenuItem("Green") redMenu.addActionListener(paintChange(self, "Red")) noneMenu.addActionListener(paintChange(self, None)) greenMenu.addActionListener(paintChange(self, "Green")) colorsMenu.add(redMenu) colorsMenu.add(noneMenu) colorsMenu.add(greenMenu) self.menu = JPopupMenu("Popup") self.menu.add(colorsMenu) self.tabs = JTabbedPane() self.tabs.addTab("Request", self._requestViewer.getComponent()) self.tabs.addTab("Response", self._responseViewer.getComponent()) self.tabs.addTab("Vulnerability", self.pnl) self.tabs.addTab("Project Settings", self.projectSettings) self.tabs.setSelectedIndex(2) self._splitpane.setRightComponent(self.tabs) def initCallbacks(self): # ## init callbacks # # customize our UI components self._callbacks.customizeUiComponent(self._splitpane) self._callbacks.customizeUiComponent(self.logTable) self._callbacks.customizeUiComponent(self.scrollPane) self._callbacks.customizeUiComponent(self.tabs) self._callbacks.registerContextMenuFactory(self) # add the custom tab to Burp's UI self._callbacks.addSuiteTab(self) def loadVulnerabilities(self, projPath): self.clearList(None) selected = False for root, dirs, files in os.walk(projPath): # make it go only for dirs for dirName in dirs: xmlPath = projPath+"/"+dirName+"/vulnerability.xml" # xmlPath = xmlPath.replace("/","//") document = self.getXMLDoc(xmlPath) nodeList = document.getDocumentElement().getChildNodes() vulnName = nodeList.item(0).getTextContent() severity = nodeList.item(1).getTextContent() description = nodeList.item(2).getTextContent() mitigation = nodeList.item(3).getTextContent() color = nodeList.item(4).getTextContent() test = vulnerability(vulnName,severity,description,mitigation,color) self._lock.acquire() row = self._log.size() self._log.add(test) self.fireTableRowsInserted(row, row) self._lock.release() if vulnName == self.vulnName.getText(): self.logTable.setRowSelectionInterval(row,row) selected = True if selected == False and self._log.size() > 0: self.logTable.setRowSelectionInterval(0, 0) self.loadVulnerability(self._log.get(0)) def createSection(self, sectioName): self.config.read('config.ini') if not (sectioName in self.config.sections()): self.config.add_section(sectioName) cfgfile = open("config.ini",'w') self.config.write(cfgfile) cfgfile.close() def saveCfg(self): f = open('config.ini', 'w') self.config.write(f) f.close() def getXMLDoc(self, xmlPath): try: document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlPath) return document except: self._extender.popup("XML file not found") return def saveXMLDoc(self, doc, xmlPath): transformerFactory = TransformerFactory.newInstance() transformer = transformerFactory.newTransformer() source = DOMSource(doc) result = StreamResult(File(xmlPath)) transformer.transform(source, result) def generateReport(self,event): if self.reportType.getSelectedItem() == "HTML": path = self.reportToHTML() if self.reportType.getSelectedItem() == "XLSX": path = self.reportToXLS() if self.reportType.getSelectedItem() == "DOCX": path = self.generateReportFromDocxTemplate('template.docx',"newfile.docx", 'word/document.xml') n = JOptionPane.showConfirmDialog(None, "Report generated successfuly:\n%s\nWould you like to open it?" % (path), "PT Manager", JOptionPane.YES_NO_OPTION) if n == JOptionPane.YES_OPTION: os.system('"' + path + '"') # Bug! stucking burp until the file get closed def exportProj(self,event): self.chooser.setDialogTitle("Save project") Ffilter = FileNameExtensionFilter("Zip files", ["zip"]) self.chooser.setFileFilter(Ffilter) returnVal = self.chooser.showSaveDialog(None) if returnVal == JFileChooser.APPROVE_OPTION: dst = str(self.chooser.getSelectedFile()) shutil.make_archive(dst,"zip",self.getCurrentProjPath()) self.popup("Project export successfuly") def importProj(self,event): self.chooser.setDialogTitle("Select project zip to directory") Ffilter = FileNameExtensionFilter("Zip files", ["zip"]) self.chooser.setFileFilter(Ffilter) returnVal = self.chooser.showOpenDialog(None) if returnVal == JFileChooser.APPROVE_OPTION: zipPath = str(self.chooser.getSelectedFile()) self.chooser.setDialogTitle("Select project directory") self.chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY) returnVal = self.chooser.showOpenDialog(None) if returnVal == JFileChooser.APPROVE_OPTION: projPath = str(self.chooser.getSelectedFile()) + "/PTManager" with zipfile.ZipFile(zipPath, "r") as z: z.extractall(projPath) xmlPath = projPath + "/project.xml" document = self.getXMLDoc(xmlPath) nodeList = document.getDocumentElement().getChildNodes() projName = nodeList.item(0).getTextContent() nodeList.item(1).setTextContent(projPath) self.saveXMLDoc(document, xmlPath) self.config.set('projects', projName, projPath) self.saveCfg() self.reloadProjects() self.currentProject.getModel().setSelectedItem(projName) self.clearVulnerabilityTab() def reportToXLS(self): if not xlsxwriterImported: self.popup("xlsxwriter library is not imported") return workbook = xlsxwriter.Workbook(self.getCurrentProjPath() + '/PT Manager Report.xlsx') worksheet = workbook.add_worksheet() bold = workbook.add_format({'bold': True}) worksheet.write(0, 0, "Vulnerability Name", bold) worksheet.write(0, 1, "Threat Level", bold) worksheet.write(0, 2, "Description", bold) worksheet.write(0, 3, "Mitigation", bold) row = 1 for i in range(0,self._log.size()): worksheet.write(row, 0, self._log.get(i).getName()) worksheet.write(row, 1, self._log.get(i).getSeverity()) worksheet.write(row, 2, self._log.get(i).getDescription()) worksheet.write(row, 3, self._log.get(i).getMitigation()) row = row + 1 # add requests and images as well workbook.close() return self.getCurrentProjPath() + '/PT Manager Report.xlsx' def reportToHTML(self): htmlContent = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="he" dir="ltr"> <head> <title>PT Manager Report</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style> body { background-repeat: no-repeat; background-attachment: fixed; font-family: Arial,Tahoma,sens-serif; font-size: 13px; margin: auto; } #warpcenter { width: 900px; margin: 0px auto; } table { border: 2px dashed #000000; } td { border-top: 2px dashed #000000; padding: 10px; } img { border: 0px; } </style> <script language="javascript"> function divHideShow(divToHideOrShow) { var div = document.getElementById(divToHideOrShow); if (div.style.display == "block") { div.style.display = "none"; } else { div.style.display = "block"; } } </script> </head> <body> <div id="warpcenter"> <h1> PT Manager Report </h1> <h2> Project: %s</h1> """ % (self.projName.getText()) for i in range(0,self._log.size()): name = self._log.get(i).getName() request = "None" response = "None" path = self.getVulnReqResPath("request",name) if os.path.exists(path): request = self.newlineToBR(self.getFileContent(path)) path = self.getVulnReqResPath("response",name) if os.path.exists(path): response = self.newlineToBR(self.getFileContent(path)) images = "" for fileName in os.listdir(self.projPath.getText()+"/"+self.clearStr(name)): if fileName.endswith(".jpg"): images += "%s<br><img src=\"%s\"><br><br>" % (fileName, self.projPath.getText()+"/"+self.clearStr(name) + "/" + fileName) description = self.newlineToBR(self._log.get(i).getDescription()) mitigation = self.newlineToBR(self._log.get(i).getMitigation()) htmlContent += self.convertVulntoTable(i,name,self._log.get(i).getSeverity(), description,mitigation, request, response, images) htmlContent += "</div></body></html>" f = open(self.getCurrentProjPath() + '/PT Manager Report.html', 'w') f.writelines(htmlContent) f.close() return self.getCurrentProjPath() + '/PT Manager Report.html' def newlineToBR(self,string): return "<br />".join(string.split("\n")) def getFileContent(self,path): f = open(path, "rb") content = f.read() f.close() return content def convertVulntoTable(self, number, name, severity, description, mitigation, request = "None", response = "None", images = "None"): return """<div style="width: 100%%;height: 30px;text-align: center;background-color:#E0E0E0;font-size: 17px;font-weight: bold;color: #000;padding-top: 10px;">%s <a href="javascript:divHideShow('Table_%s');" style="color:#191970">(OPEN / CLOSE)</a></div> <div id="Table_%s" style="display: none;"> <table width="100%%" cellspacing="0" cellpadding="0" style="margin: 0px auto;text-align: left;border-top: 0px;"> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Threat Level: </span> <span style="color:#8b8989">%s</span> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Description</span> <a href="javascript:divHideShow('Table_%s_Command_03');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_03" style="display: none;margin-top: 25px;"> %s </div> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Mitigration</span> <a href="javascript:divHideShow('Table_%s_Command_04');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_04" style="display: none;margin-top: 25px;"> %s <b> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Request</span> <a href="javascript:divHideShow('Table_%s_Command_05');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_05" style="display: none;margin-top: 25px;"> %s <b> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Response</span> <a href="javascript:divHideShow('Table_%s_Command_06');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_06" style="display: none;margin-top: 25px;"> %s <b> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Images</span> <a href="javascript:divHideShow('Table_%s_Command_07');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_07" style="display: none;margin-top: 25px;"> %s <b> </td> </tr> </table> </div><br><br>""" % (name,number,number,severity,number,number,description,number,number,mitigation,number,number,request,number,number,response,number,number,images) def clearVulnerabilityTab(self, rmVuln=True): if rmVuln: self.vulnName.setText("") self.descriptionString.setText("") self.mitigationStr.setText("") self.colorCombo.setSelectedIndex(0) self.threatLevel.setSelectedIndex(0) self.screenshotsList.clear() self.addButton.setText("Add") self.firstPic.setIcon(None) def saveRequestResponse(self, type, requestResponse, vulnName): path = self.getVulnReqResPath(type,vulnName) f = open(path, 'wb') f.write(requestResponse) f.close() def openProj(self, event): os.system('explorer ' + self.projPath.getText()) def getVulnReqResPath(self, requestOrResponse, vulnName): return self.getCurrentProjPath() + "/" + self.clearStr(vulnName) + "/"+requestOrResponse+"_" + self.clearStr(vulnName) def htmlEscape(self,data): return data.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"').replace("'", ''') def generateReportFromDocxTemplate(self, zipname, newZipName, filename): newZipName = self.getCurrentProjPath() + "/" + newZipName with zipfile.ZipFile(zipname, 'r') as zin: with zipfile.ZipFile(newZipName, 'w') as zout: zout.comment = zin.comment for item in zin.infolist(): if item.filename != filename: zout.writestr(item, zin.read(item.filename)) else: xml_content = zin.read(item.filename) result = re.findall("(.*)<w:body>(?:.*)<\/w:body>(.*)",xml_content)[0] newXML = result[0] templateBody = re.findall("<w:body>(.*)<\/w:body>", xml_content)[0] newBody = "" for i in range(0,self._log.size()): tmp = templateBody tmp = tmp.replace("$vulnerability", self.htmlEscape(self._log.get(i).getName())) tmp = tmp.replace("$severity", self.htmlEscape(self._log.get(i).getSeverity())) tmp = tmp.replace("$description", self.htmlEscape(self._log.get(i).getDescription())) tmp = tmp.replace("$mitigation", self.htmlEscape(self._log.get(i).getMitigation())) newBody = newBody + tmp newXML = newXML + newBody newXML = newXML + result[1] with zipfile.ZipFile(newZipName, mode='a', compression=zipfile.ZIP_DEFLATED) as zf: zf.writestr(filename, newXML) return newZipName def chooseProjPath(self, event): self.chooser.setDialogTitle("Select target directory") self.chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY) returnVal = self.chooser.showOpenDialog(None) if returnVal == JFileChooser.APPROVE_OPTION: projPath = str(self.chooser.getSelectedFile()) + "/PTManager" os.makedirs(projPath) self.projPath.setText(projPath) def reloadProjects(self): self.currentProject.setModel(DefaultComboBoxModel(self.config.options('projects'))) def rmProj(self, event): if self.popUpAreYouSure() == JOptionPane.YES_OPTION: self._requestViewer.setMessage("None", False) self._responseViewer.setMessage("None", False) shutil.rmtree(self.projPath.getText()) self.config.remove_option('projects',self.currentProject.getSelectedItem()) self.reloadProjects() self.currentProject.setSelectedIndex(0) self.loadVulnerabilities(self.projPath.getText()) def popup(self,msg): JOptionPane.showMessageDialog(None,msg) def addProj(self, event): projPath = self.projPath.getText() if projPath == None or projPath == "": self.popup("Please select path") return self.config.set('projects', self.projName.getText(), projPath) self.saveCfg() xml = ET.Element('project') name = ET.SubElement(xml, "name") path = ET.SubElement(xml, "path") details = ET.SubElement(xml, "details") autoSaveMode = ET.SubElement(xml, "autoSaveMode") name.text = self.projName.getText() path.text = projPath details.text = self.projDetails.getText() autoSaveMode.text = str(self.autoSave.isSelected()) tree = ET.ElementTree(xml) try: tree.write(self.getCurrentProjPath()+'/project.xml') except: self.popup("Invalid path") return self.reloadProjects() self.clearVulnerabilityTab() self.clearList(None) self.currentProject.getModel().setSelectedItem(self.projName.getText()) def resize(self, image, width, height): bi = BufferedImage(width, height, BufferedImage.TRANSLUCENT) g2d = bi.createGraphics() g2d.addRenderingHints(RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY)) g2d.drawImage(image, 0, 0, width, height, None) g2d.dispose() return bi; def clearStr(self, var): return var.replace(" " , "_").replace("\\" , "").replace("/" , "").replace(":" , "").replace("*" , "").replace("?" , "").replace("\"" , "").replace("<" , "").replace(">" , "").replace("|" , "").replace("(" , "").replace(")" , "") def popUpAreYouSure(self): dialogResult = JOptionPane.showConfirmDialog(None,"Are you sure?","Warning",JOptionPane.YES_NO_OPTION) if dialogResult == 0: return 0 return 1 def removeSS(self,event): if self.popUpAreYouSure() == JOptionPane.YES_OPTION: os.remove(self.getCurrentVulnPath() + "/" + self.ssList.getSelectedValue()) self.ssList.getModel().remove(self.ssList.getSelectedIndex()) self.firstPic.setIcon(ImageIcon(None)) # check if there is images and select the first one # bug in linux def addSS(self,event): clipboard = Toolkit.getDefaultToolkit().getSystemClipboard() try: image = clipboard.getData(DataFlavor.imageFlavor) except: self.popup("Clipboard not contains image") return vulnPath = self.projPath.getText() + "/" + self.clearStr(self.vulnName.getText()) if not os.path.exists(vulnPath): os.makedirs(vulnPath) name = self.clearStr(self.vulnName.getText()) + str(random.randint(1, 99999))+".jpg" fileName = self.projPath.getText()+"/"+ self.clearStr(self.vulnName.getText()) + "/" + name file = File(fileName) bufferedImage = BufferedImage(image.getWidth(None), image.getHeight(None), BufferedImage.TYPE_INT_RGB); g = bufferedImage.createGraphics(); g.drawImage(image, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), Color.WHITE, None); ImageIO.write(bufferedImage, "jpg", file) self.addVuln(self) self.ssList.setSelectedValue(name,True) def rmVuln(self, event): if self.popUpAreYouSure() == JOptionPane.YES_OPTION: self._requestViewer.setMessage("None", False) self._responseViewer.setMessage("None", False) shutil.rmtree(self.getCurrentVulnPath()) self.clearVulnerabilityTab() self.loadVulnerabilities(self.getCurrentProjPath()) def addVuln(self, event): if self.colorCombo.getSelectedItem() == "Color:": colorTxt = None else: colorTxt = self.colorCombo.getSelectedItem() self._lock.acquire() row = self._log.size() vulnObject = vulnerability(self.vulnName.getText(),self.threatLevel.getSelectedItem(),self.descriptionString.getText(),self.mitigationStr.getText() ,colorTxt) self._log.add(vulnObject) self.fireTableRowsInserted(row, row) self._lock.release() vulnPath = self.projPath.getText() + "/" + self.clearStr(self.vulnName.getText()) if not os.path.exists(vulnPath): os.makedirs(vulnPath) xml = ET.Element('vulnerability') name = ET.SubElement(xml, "name") severity = ET.SubElement(xml, "severity") description = ET.SubElement(xml, "description") mitigation = ET.SubElement(xml, "mitigation") color = ET.SubElement(xml, "color") name.text = self.vulnName.getText() severity.text = self.threatLevel.getSelectedItem() description.text = self.descriptionString.getText() mitigation.text = self.mitigationStr.getText() color.text = colorTxt tree = ET.ElementTree(xml) tree.write(vulnPath+'/vulnerability.xml') self.loadVulnerabilities(self.getCurrentProjPath()) self.loadVulnerability(vulnObject) def vulnNameChanged(self): if os.path.exists(self.getCurrentVulnPath()) and self.vulnName.getText() != "": self.addButton.setText("Update") elif self.addButton.getText() != "Add": options = ["Create a new vulnerability", "Change current vulnerability name"] n = JOptionPane.showOptionDialog(None, "Would you like to?", "Vulnerability Name", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, None, options, options[0]); if n == 0: self.clearVulnerabilityTab(False) self.addButton.setText("Add") else: newName = JOptionPane.showInputDialog( None, "Enter new name:", "Vulnerability Name", JOptionPane.PLAIN_MESSAGE, None, None, self.vulnName.getText()) row = self.logTable.getSelectedRow() old = self.logTable.getValueAt(row,1) self.changeVulnName(newName,old) def changeVulnName(self,new,old): newpath = self.getCurrentProjPath() + "/" + new oldpath = self.getCurrentProjPath() + "/" + old os.rename(oldpath,newpath) self.changeCurrentVuln(new,0, newpath + "/vulnerability.xml") def getCurrentVulnPath(self): return self.projPath.getText() + "/" + self.clearStr(self.vulnName.getText()) def getCurrentProjPath(self): return self.projPath.getText() def loadSS(self, imgPath): image = ImageIO.read(File(imgPath)) if image.getWidth() <= 550 and image.getHeight() <= 400: self.firstPic.setIcon(ImageIcon(image)) self.firstPic.setSize(image.getWidth(),image.getHeight()) else: self.firstPic.setIcon(ImageIcon(self.resize(image,550, 400))) self.firstPic.setSize(550,400) def clearProjectTab(self): self.projPath.setText("") self.projDetails.setText("") def clearList(self, event): self._lock.acquire() self._log = ArrayList() row = self._log.size() self.fireTableRowsInserted(row, row) self._lock.release() # # implement IContextMenuFactory # def createMenuItems(self, invocation): responses = invocation.getSelectedMessages(); if responses > 0: ret = LinkedList() requestMenuItem = JMenuItem("Send to PT Manager"); requestMenuItem.addActionListener(handleMenuItems(self,responses[0], "request")) ret.add(requestMenuItem); return(ret); return null; # # implement ITab # def getTabCaption(self): return "PT Manager" def getUiComponent(self): return self._splitpane # # extend AbstractTableModel # def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 3 def getColumnName(self, columnIndex): if columnIndex == 0: return "#" if columnIndex == 1: return "Vulnerability Name" if columnIndex == 2: return "Threat Level" return "" def getValueAt(self, rowIndex, columnIndex): vulnObject = self._log.get(rowIndex) if columnIndex == 0: return rowIndex+1 if columnIndex == 1: return vulnObject.getName() if columnIndex == 2: return vulnObject.getSeverity() if columnIndex == 3: return vulnObject.getMitigation() if columnIndex == 4: return vulnObject.getColor() return "" def changeCurrentVuln(self,value,fieldNumber, xmlPath = "def"): if xmlPath == "def": xmlPath = self.getCurrentVulnPath() + "/vulnerability.xml" document = self.getXMLDoc(xmlPath) nodeList = document.getDocumentElement().getChildNodes() nodeList.item(fieldNumber).setTextContent(value) self.saveXMLDoc(document, xmlPath) self.loadVulnerabilities(self.getCurrentProjPath()) def loadVulnerability(self, vulnObject): self.addButton.setText("Update") self.vulnName.setText(vulnObject.getName()) self.threatLevel.setSelectedItem(vulnObject.getSeverity()) self.descriptionString.setText(vulnObject.getDescription()) self.mitigationStr.setText(vulnObject.getMitigation()) if vulnObject.getColor() == "" or vulnObject.getColor() == None: self.colorCombo.setSelectedItem("Color:") else: self.colorCombo.setSelectedItem(vulnObject.getColor()) self.screenshotsList.clear() for fileName in os.listdir(self.projPath.getText()+"/"+self.clearStr(vulnObject.getName())): if fileName.endswith(".jpg"): self.screenshotsList.addElement(fileName) imgPath = self.projPath.getText()+"/"+self.clearStr(vulnObject.getName())+'/'+fileName # imgPath = imgPath.replace("/","//") self.loadSS(imgPath) if (self.screenshotsList.getSize() == 0): self.firstPic.setIcon(None) else: self.ssList.setSelectedIndex(0) path = self.getVulnReqResPath("request",vulnObject.getName()) if os.path.exists(path): f = self.getFileContent(path) self._requestViewer.setMessage(f, False) else: self._requestViewer.setMessage("None", False) path = self.getVulnReqResPath("response",vulnObject.getName()) if os.path.exists(path): f = self.getFileContent(path) self._responseViewer.setMessage(f, False) else: self._responseViewer.setMessage("None", False)
class WorkHelper(JFrame): def __init__(self): super(WorkHelper, self).__init__() self.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard() #self.initUI() #def initUI(self): #panel = JPanel() #self.getContentPane().add(panel) ############################################################# # Layout layout = GroupLayout(self.getContentPane()) self.getContentPane().setLayout(layout) layout.setAutoCreateGaps(True) layout.setAutoCreateContainerGaps(True) ############################################################# ############################################################# # Scroll Area Input + Output Larea1 = JLabel("InputArea:") Larea2 = JLabel("OutputArea:") Sarea1 = JScrollPane() Sarea2 = JScrollPane() self.area1 = JTextArea() self.area1.setToolTipText("Input Area") self.area1.setEditable(True) self.area1.setBorder(BorderFactory.createLineBorder(Color.gray)) Sarea1.setPreferredSize(Dimension(300,100)) Sarea1.getViewport().setView((self.area1)) self.area2 = JTextArea() self.area2.setToolTipText("Output Area") self.area2.setEditable(False) self.area2.setBorder(BorderFactory.createLineBorder(Color.gray)) Sarea2.setPreferredSize(Dimension(300,100)) Sarea2.getViewport().setView((self.area2)) ############################################################# ############################################################# # Buttons self.cCurly = JCheckBox("Curly"); self.cCurly.setToolTipText("When 'Checked' Curly Brackets will surround the Categories") self.cCurly.setSelected(1) self.cCtClipB = JCheckBox("Auto-Copy"); self.cCtClipB.setToolTipText("When 'Checked' after the Categories are created they will added to the clipboard") self.cCtClipB.setSelected(1) self.cSemiC = JCheckBox("SemiColumn"); self.cSemiC.setToolTipText("When 'Checked' after the Categories are created at the end will be a semicolomn") self.cSemiC.setSelected(1) bRemoveNBSP_L = JButton("Clean LText", actionPerformed=self.bRemoveNBSP_L) bRemoveNBSP_L.setToolTipText("Removes Spaces, Tabs from the start of every text line from the input Area") bRemoveNBSP_R = JButton("Clean RText", actionPerformed=self.bRemoveNBSP_R) bRemoveNBSP_R.setToolTipText("Removes Spaces, Tabs from the end of every text line from the input Area") bCopyToInput = JButton("Copy to Input", actionPerformed=self.bCopyToInput) bCopyToInput.setToolTipText("Copy the text from the Output Area to the Input Area for further Operations") bClear = JButton("Clear", actionPerformed=self.bClear) bClear.setToolTipText("Clears the text form both Input and Output text Areas") self.iStart = JTextField(maximumSize=Dimension(40,25)) self.iStart.setToolTipText("The Start Index for the Making of the Categories") self.RThis = JTextField() self.RThis = JTextField(maximumSize=Dimension(120,25)) self.RThis.setToolTipText("Text to be replaced or The Starting C_Index") self.RThat = JTextField() self.RThat = JTextField(maximumSize=Dimension(120,25)) self.RThat.setToolTipText("Text to be placed or The Finish C_Index") bSandReplace = JButton("Replace Text", actionPerformed=self.bSandReplace) bSandReplace.setToolTipText("Replace the text from This with Thext from That in the Text from the Input Area and displays it in the Output Area") bcCat = JButton("CreatCateg", actionPerformed=self.bcCat) bcCat.setToolTipText("Create a categorical form starting C_Index to finish C_Index; Use the above text boxes to define the indexes") bC_S = JButton("Create _Series", actionPerformed=self.bC_S) bC_S.setToolTipText("Create a series form starting C_Index to finish C_Index; Use the above text boxes to define the indexes; It will create a series for every row in the Input Area") bM_Categories = JButton("Categories", actionPerformed=self.mCategories) bM_Categories.setToolTipText("Make Categories using the lines from the Input Area") #bM_Categories = JButton(maximumSize=Dimension(40,25)) # de incercat daca merge cu ; sa grupezi in [dsa] elementele ############################################################# ############################################################# # Aplication Layout 2 groups one Horizontal and one Vertical layout.setHorizontalGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup() .addComponent(Larea1) .addComponent(Sarea1) .addComponent(Sarea2) .addComponent(bCopyToInput) .addComponent(Larea2)) .addGroup(layout.createParallelGroup() .addGroup(layout.createSequentialGroup() .addComponent(bM_Categories) .addComponent(self.iStart)) .addGroup(layout.createSequentialGroup() .addComponent(self.cCurly) .addComponent(self.cSemiC) .addComponent(self.cCtClipB)) .addGroup(layout.createSequentialGroup() .addComponent(bRemoveNBSP_L) .addComponent(bRemoveNBSP_R)) .addGroup(layout.createSequentialGroup() .addComponent(self.RThis) .addComponent(self.RThat)) .addGroup(layout.createSequentialGroup() .addComponent(bSandReplace) .addComponent(bcCat)) .addGroup(layout.createSequentialGroup() .addComponent(bC_S)) .addComponent(bClear)) ) layout.setVerticalGroup(layout.createSequentialGroup() .addComponent(Larea1) .addGroup(layout.createParallelGroup() .addComponent(Sarea1) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup() .addComponent(bM_Categories) .addComponent(self.iStart)) .addGroup(layout.createParallelGroup() .addComponent(self.cCurly) .addComponent(self.cSemiC) .addComponent(self.cCtClipB)) .addGroup(layout.createParallelGroup() .addComponent(bRemoveNBSP_L) .addComponent(bRemoveNBSP_R)) .addGroup(layout.createParallelGroup() .addComponent(self.RThis) .addComponent(self.RThat)) .addGroup(layout.createParallelGroup() .addComponent(bSandReplace) .addComponent(bcCat)) .addGroup(layout.createParallelGroup() .addComponent(bC_S)) ) ) .addGroup(layout.createParallelGroup() .addComponent(bCopyToInput) .addComponent(bClear)) .addComponent(Larea2) .addGroup(layout.createParallelGroup() .addComponent(Sarea2)) ) #layout.linkSize(SwingConstants.HORIZONTAL, [ok, bCopyToInput, close, bM_Categories]) layout.linkSize(SwingConstants.HORIZONTAL, [self.RThis,self.RThat,bRemoveNBSP_L,bRemoveNBSP_R,bCopyToInput,bM_Categories,bSandReplace,bcCat,bC_S]) #layout.linkSize(SwingConstants.HORIZONTAL, [self.cCurly,bM_Categories]) ############################################################# ############################################################# # Aplication Settings self.pack() #self.setPreferredSize(Dimension(1000, 1000)) self.setTitle("Workhelper") self.setSize(800, 500) self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) self.setLocationRelativeTo(None) self.setVisible(True) ############################################################# ############################################################# # WorkHelper class methods: def onQuit(self, e): "@sig public void setExpression(java.lang.String e)" System.exit(0) # def addToClipBoard(self, text): # "@sig public void setExpression(java.lang.String text)" # command = 'echo ' + text.strip() + '| clip' # os.system(command) # brute method for pasting into clipboard on windows def mCategories(self, e): "@sig public void setExpression(java.lang.String e)" """ Takes every line of text form the Input Area and by using a string composotion it creates the output in the SPSS dimension categories format. """ try: StartIndex = int(self.iStart.getText()) except ValueError: StartIndex=1 text=self.area1.getText().rstrip() counter=StartIndex lastindex=0 textO="" for i in range(0,len(text)): if text[i]=='\n': textO=textO+("_"+str(counter)+' "'+text[lastindex:i]+'",\n') lastindex=i+1 counter=counter+1 if len(text[lastindex:len(text)])>0: textO=textO+("_"+str(counter)+' "'+text[lastindex:len(text)]+'"') if len(textO)>0: if self.cCurly.isSelected(): textO = "{\n"+ textO + "\n}" if self.cSemiC.isSelected(): textO = textO + ";" self.copyToClipboard(textO) self.area2.setText(textO) def copyToClipboard(self, text): if self.cCtClipB.isSelected(): stringSelection = StringSelection(text) self.clipboard.setContents(stringSelection, None) def bCopyToInput(self, e): "@sig public void setExpression(java.lang.String e)" """Copy the Text from the Output Area to the input Area for further operations""" self.area1.setText(self.area2.getText()) def bRemoveNBSP_L(self, e): "@sig public void setExpression(java.lang.String e)" text=self.area1.getText().rstrip() textO="" lastindex=0 for i in range(0,len(text)): if text[i] == '\n': textO = textO+text[lastindex:i].lstrip()+"\n" lastindex=i+1 #print(text[0:i].lstrip()+'\n') if len(text[lastindex:len(text)])>0: textO=textO+text[lastindex:len(text)].lstrip() self.area2.setText(textO) def bRemoveNBSP_R(self, e): "@sig public void setExpression(java.lang.String e)" text=self.area1.getText().rstrip() textO="" lastindex=0 for i in range(0,len(text)): if text[i] == '\n': textO = textO+text[lastindex:i].rstrip()+"\n" lastindex=i+1 #print(text[0:i].lstrip()+'\n') if len(text[lastindex:len(text)])>0: textO=textO+text[lastindex:len(text)].rstrip() self.area2.setText(textO) def bClear(self, e): "@sig public void setExpression(java.lang.String e)" self.area1.setText("") self.area2.setText("") def bcCat(self, e): "@sig public void setExpression(java.lang.String e)" try: StartIndex = int(self.RThis.getText()) except ValueError: StartIndex=1 try: FinishIndex = int(self.RThat.getText()) except ValueError: FinishIndex=1 cCats="" for i in range(StartIndex,FinishIndex+1): if i<>FinishIndex: cCats=cCats+"_"+str(i)+"," else: cCats=cCats+"_"+str(i) if StartIndex<FinishIndex: cCats="{"+cCats+"}" self.copyToClipboard(cCats) self.area2.setText(cCats) def bSandReplace(self, e): self.area2.setText(self.area1.getText().replace(self.RThis.getText(),self.RThat.getText())) def bC_S(self, e): "@sig public void setExpression(java.lang.String e)" try: StartIndex = int(self.RThis.getText()) except ValueError: StartIndex=1 try: FinishIndex = int(self.RThat.getText()) except ValueError: FinishIndex=1 if StartIndex<FinishIndex: text=self.area1.getText().rstrip() lastindex=0 textO="" for i in range(0,len(text)): if text[i]=='\n': counter=StartIndex for j in range(StartIndex,FinishIndex+1): textO=textO+(text[lastindex:i]+"_"+str(counter)+" ") counter=counter+1 lastindex=i+1 textO=textO+'\n' #if len(text[lastindex:len(text)])>0: # textO=textO+("_"+str(counter)+' "'+text[lastindex:len(text)]+'"') if lastindex==0 and len(text)>0: counter=StartIndex for j in range(StartIndex,FinishIndex+1): textO=textO+(text[lastindex:i]+"_"+str(counter)+" ") counter=counter+1 if len(textO)>0: self.copyToClipboard(textO) self.area2.setText(textO)
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, IContextMenuFactory): def registerExtenderCallbacks(self, callbacks): # smart xss feature (print conclusion and observation) # mark resulsts # add automatic check pages in the same domain self.tagPayloads = [ "<b>test", "<b onmouseover=test()>test", "<img src=err onerror=test()>", "<script>test</script>" "", "<scr ipt>test</scr ipt>", "<SCRIPT>test;</SCRIPT>", "<scri<script>pt>test;</scr</script>ipt>", "<SCRI<script>PT>test;</SCR</script>IPT>", "<scri<scr<script>ipt>pt>test;</scr</sc</script>ript>ipt>", "<IMG \"\"\"><SCRIPT>test</SCRIPT>\">", "<IMG '''><SCRIPT>test</SCRIPT>'>", "<SCR%00IPT>test</SCR%00IPT>", "<IFRAME SRC='f' onerror=\"test\"></IFRAME>", "<IFRAME SRC='f' onerror='test'></IFRAME>", "<<SCRIPT>test//<</SCRIPT>", "<img src=\"1\" onerror=\"test\">", "<img src='1' onerror='test'", "<STYLE TYPE=\"text/javascript\">test;</STYLE>", "<<SCRIPT>test//<</SCRIPT>" ] self.attributePayloads = [ "\"\"\"><SCRIPT>test", "'''><SCRIPT>test'", "\"><script>test</script>", "\"><script>test</script><\"", "'><script>test</script>", "'><script>test</script><'", "\";test;\"", "';test;'", ";test;", "\";test;//", "\"onmouseover=test ", "onerror=\"test\"", "onerror='test'", "onload=\"test\"", "onload='test'" ] self.xssKey = 'xssme' # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("XSSor") self.affectedResponses = ArrayList() self._log = ArrayList() self._lock = Lock() # main split pane self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) # table of log entries logTable = Table(self) scrollPane = JScrollPane(logTable) self._splitpane.setLeftComponent(scrollPane) # tabs with request/response viewers tabs = JTabbedPane() self._requestViewer = callbacks.createMessageEditor(self, False) self._responseViewer = callbacks.createMessageEditor(self, False) tabs.addTab("Request", self._requestViewer.getComponent()) tabs.addTab("Response", self._responseViewer.getComponent()) clearAPListBtn = JButton("Clear List", actionPerformed=self.clearAPList) clearAPListBtn.setBounds(10, 85, 120, 30) apListLabel = JLabel('Affected Pages List:') apListLabel.setBounds(10, 10, 140, 30) self.affectedModel = DefaultListModel() self.affectedList = JList(self.affectedModel) self.affectedList.addListSelectionListener(listSelectedChange(self)) scrollAList = JScrollPane(self.affectedList) scrollAList.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED) scrollAList.setBounds(150, 10, 550, 200) scrollAList.setBorder(LineBorder(Color.BLACK)) APtabs = JTabbedPane() self._requestAPViewer = callbacks.createMessageEditor(self, False) self._responseAPViewer = callbacks.createMessageEditor(self, False) APtabs.addTab("Request", self._requestAPViewer.getComponent()) APtabs.addTab("Affeced Page Response", self._responseAPViewer.getComponent()) APtabs.setBounds(0, 250, 700, 350) APtabs.setSelectedIndex(1) self.APpnl = JPanel() self.APpnl.setBounds(0, 0, 1000, 1000) self.APpnl.setLayout(None) self.APpnl.add(scrollAList) self.APpnl.add(clearAPListBtn) self.APpnl.add(APtabs) self.APpnl.add(apListLabel) tabs.addTab("Affected Pages", self.APpnl) self.intercept = 0 ## init conf panel startLabel = JLabel("Plugin status:") startLabel.setBounds(10, 10, 140, 30) payloadLabel = JLabel("Basic Payload:") payloadLabel.setBounds(10, 50, 140, 30) self.basicPayload = "<script>alert(1)</script>" self.basicPayloadTxt = JTextArea(self.basicPayload, 5, 30) self.basicPayloadTxt.setBounds(120, 50, 305, 30) self.bruteForceMode = JCheckBox("Brute Force Mode") self.bruteForceMode.setBounds(120, 80, 300, 30) self.bruteForceMode.addItemListener(handleBFModeChange(self)) self.tagPayloadsCheck = JCheckBox("Tag paylods") self.tagPayloadsCheck.setBounds(120, 100, 300, 30) self.tagPayloadsCheck.setSelected(True) self.tagPayloadsCheck.setEnabled(False) self.tagPayloadsCheck.addItemListener(handleBFModeList(self)) self.attributePayloadsCheck = JCheckBox("Attribute payloads") self.attributePayloadsCheck.setBounds(260, 100, 300, 30) self.attributePayloadsCheck.setSelected(True) self.attributePayloadsCheck.setEnabled(False) self.attributePayloadsCheck.addItemListener(handleBFModeList(self)) payloadListLabel = JLabel("Payloads list (for BF mode):") payloadListLabel.setBounds(10, 130, 140, 30) self.payloadsModel = DefaultListModel() self.payloadsList = JList(self.payloadsModel) scrollPayloadsList = JScrollPane(self.payloadsList) scrollPayloadsList.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED) scrollPayloadsList.setBounds(120, 170, 300, 200) scrollPayloadsList.setBorder(LineBorder( Color.BLACK)) # add buttons to remove payloads and add for payload in self.tagPayloads: self.payloadsModel.addElement(payload) for payload in self.attributePayloads: self.payloadsModel.addElement(payload) self.startButton = JButton("XSSor is off", actionPerformed=self.startOrStop) self.startButton.setBounds(120, 10, 120, 30) self.startButton.setBackground(Color(255, 100, 91, 255)) consoleTab = JTabbedPane() self.consoleLog = JTextArea("", 5, 30) scrollLog = JScrollPane(self.consoleLog) scrollLog.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED) scrollLog.setBounds(120, 170, 550, 200) scrollLog.setBorder(LineBorder(Color.BLACK)) scrollLog.getVerticalScrollBar().addAdjustmentListener( autoScrollListener(self)) consoleTab.addTab("Console", scrollLog) consoleTab.setBounds(0, 400, 500, 200) self.pnl = JPanel() self.pnl.setBounds(0, 0, 1000, 1000) self.pnl.setLayout(None) self.pnl.add(self.startButton) self.pnl.add(startLabel) self.pnl.add(payloadLabel) self.pnl.add(self.basicPayloadTxt) self.pnl.add(self.bruteForceMode) self.pnl.add(payloadListLabel) self.pnl.add(scrollPayloadsList) self.pnl.add(self.attributePayloadsCheck) self.pnl.add(self.tagPayloadsCheck) self.pnl.add(consoleTab) tabs.addTab("Configuration", self.pnl) tabs.setSelectedIndex(3) self._splitpane.setRightComponent(tabs) # customize our UI components callbacks.customizeUiComponent(self._splitpane) callbacks.customizeUiComponent(logTable) callbacks.customizeUiComponent(scrollPane) callbacks.customizeUiComponent(tabs) # add the custom tab to Burp's UI callbacks.addSuiteTab(self) # register ourselves as an HTTP listener callbacks.registerHttpListener(self) self._callbacks.registerContextMenuFactory(self) print "Thank you for installing XSSor v0.1 extension" print "Created by Barak Tawily" print "\nGithub:\nhttps://github.com/Quitten/XSSor" return # # implement ITab # def getTabCaption(self): return "XSSor" def getUiComponent(self): return self._splitpane # # implement IHttpListener # def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): if self.intercept == 1: if toolFlag == 4: # only process requests if not messageIsRequest: self.checkForKey(messageInfo) return def printLog(self, message): self.consoleLog.setText(self.consoleLog.getText() + '\r\n' + message) def checkXSS(self, messageInfo, urlStr, requestBody, currentPayload): self.printLog('trying exploit with the payload: ' + currentPayload) requestURL = URL(urlStr.replace(self.xssKey, currentPayload)) requestBody = requestBody.replace(self.xssKey, urllib.pathname2url(currentPayload)) httpService = self._helpers.buildHttpService( str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https") response = self._callbacks.makeHttpRequest(httpService, requestBody) responseInfo = self._helpers.analyzeResponse(response.getResponse()) analyzedResponse = self._helpers.bytesToString(response.getResponse( )) # change body offeset + make ui for affeccted pages responseBody = analyzedResponse.encode('utf-8') vulnOrNot = 'no' if currentPayload in responseBody: self.printLog('payload: ' + currentPayload + ' found to be vulnarble') vulnOrNot = 'yes' # mark the payload if not len(self.affectedResponses) == 0: for request in self.affectedResponses: # bug in case of no response in messageinfo self.printLog('checking affeccted page' + str(request.getUrl())) requestURL = request.getUrl() httpService = self._helpers.buildHttpService( str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https") affectedPageResponse = self._callbacks.makeHttpRequest( httpService, request.getRequest()) analyzedResponse = self._helpers.bytesToString( affectedPageResponse.getResponse()) responseBody = analyzedResponse.encode('utf-8') if currentPayload in responseBody: vulnOrNot = 'yes, affected page' self.printLog('affeccted page has been found as vulnerable') self._lock.acquire() row = self._log.size() self._log.add( LogEntry( self._helpers.analyzeRequest(response).getUrl(), self._callbacks.saveBuffersToTempFiles(response), currentPayload, vulnOrNot)) self.fireTableRowsInserted(row, row) self._lock.release() def checkForKey(self, messageInfo): currentPayload = self.tagPayloads[0] requestInfo = self._helpers.analyzeRequest(messageInfo) requestHeaders = list(requestInfo.getHeaders()) requestURL = requestInfo.getUrl() urlStr = str(requestURL) self.printLog('checking for xss key in URL: ' + urlStr) requestBody = self._helpers.bytesToString(messageInfo.getRequest()) requestBody = re.sub( 'Referer:.*\n', '', requestBody, flags=re.MULTILINE, count=1) # workaround avoid xsskey in the referer newHeaders if self.xssKey in urlStr or self.xssKey in requestBody: self.printLog('xss key has been found') if self.bruteForceMode.isSelected(): for i in range(0, self.payloadsModel.getSize()): payload = self.payloadsModel.getElementAt(i) self.checkXSS(messageInfo, urlStr, requestBody, payload) else: self.checkXSS(messageInfo, urlStr, requestBody, self.basicPayloadTxt.getText()) # # extend AbstractTableModel # def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 3 def getColumnName(self, columnIndex): if columnIndex == 0: return "URL" if columnIndex == 1: return "Payload" if columnIndex == 2: return "Vulnerable?" return "" def getValueAt(self, rowIndex, columnIndex): logEntry = self._log.get(rowIndex) if columnIndex == 0: # return self._callbacks.getToolName(logEntry._tool) return logEntry._url.toString() if columnIndex == 1: return logEntry._payload if columnIndex == 2: return logEntry._vulnOrNot return "" # # implement IMessageEditorController # this allows our request/response viewers to obtain details about the messages being displayed # def getHttpService(self): return self._currentlyDisplayedItem.getHttpService() def getRequest(self): return self._currentlyDisplayedItem.getRequest() def getResponse(self): return self._currentlyDisplayedItem.getResponse() def startOrStop(self, event): if self.startButton.getText() == "XSSor is off": self.startButton.setText("XSSor is on") self.startButton.setBackground(Color.GREEN) self.printLog('on, waiting for key word to be found (' + self.xssKey + ')') self.intercept = 1 else: self.startButton.setText("XSSor is off") self.startButton.setBackground(Color(255, 100, 91, 255)) self.intercept = 0 def clearAPList(self, event): self.affectedModel.clear() self.affectedResponses = ArrayList() # # implement IContextMenuFactory # def createMenuItems(self, invocation): responses = invocation.getSelectedMessages() if responses > 0: ret = LinkedList() affectedMenuItem = JMenuItem("XSSor: Add affected page") affectedMenuItem.addActionListener( handleMenuItems(self, responses[0], "affected")) ret.add(affectedMenuItem) return (ret) return null def addAfectedPage(self, messageInfo): self.affectedModel.addElement( str(self._helpers.analyzeRequest(messageInfo).getUrl())) self.affectedResponses.add(messageInfo)
class NewAccountGUI: def __init__(self, amgui): self.amgui = amgui self.am = amgui.acctmanager self.buildgwinfo() self.autologin = JCheckBox("Automatically Log In") self.acctname = JTextField() self.gwoptions = JPanel(doublebuffered) self.gwoptions.border = TitledBorder("Gateway Options") self.buildgwoptions("Twisted") self.mainframe = JFrame("New Account Window") self.buildpane() def buildgwinfo(self): self.gateways = { "Twisted": { "ident": JTextField(), "passwd": JPasswordField(), "host": JTextField("twistedmatrix.com"), "port": JTextField("8787"), "service": JTextField("twisted.words"), "persp": JTextField() }, "AIM": { "ident": JTextField(), "passwd": JPasswordField(), "host": JTextField("toc.oscar.aol.com"), "port": JTextField("9898") }, "IRC": { "ident": JTextField(), "passwd": JPasswordField(), "host": JTextField(), "port": JTextField("6667"), "channels": JTextField() } } self.displayorder = { "Twisted": [["Identity Name", "ident"], ["Password", "passwd"], ["Host", "host"], ["Port", "port"], ["Service Name", "service"], ["Perspective Name", "persp"]], "AIM": [["Screen Name", "ident"], ["Password", "passwd"], ["Host", "host"], ["Port", "port"]], "IRC": [["Nickname", "ident"], ["Password", "passwd"], ["Host", "host"], ["Port", "port"], ["Channels", "channels"]] } def buildgwoptions(self, gw): self.gwoptions.removeAll() self.gwoptions.layout = GridLayout(len(self.gateways[gw]), 2) for mapping in self.displayorder[gw]: self.gwoptions.add(JLabel(mapping[0])) self.gwoptions.add(self.gateways[gw][mapping[1]]) def buildpane(self): gw = JPanel(GridLayout(1, 2), doublebuffered) gw.add(JLabel("Gateway")) self.gwlist = JComboBox( self.gateways.keys()) #, actionPerformed=self.changegw) self.gwlist.setSelectedItem("Twisted") gw.add(self.gwlist) stdoptions = JPanel(GridLayout(2, 2), doublebuffered) stdoptions.border = TitledBorder("Standard Options") stdoptions.add(JLabel()) stdoptions.add(self.autologin) stdoptions.add(JLabel("Account Name")) stdoptions.add(self.acctname) buttons = JPanel(FlowLayout(), doublebuffered) buttons.add(JButton("OK", actionPerformed=self.addaccount)) buttons.add(JButton("Cancel", actionPerformed=self.cancel)) mainpane = self.mainframe.getContentPane() mainpane.layout = BoxLayout(mainpane, BoxLayout.Y_AXIS) mainpane.add(gw) mainpane.add(self.gwoptions) mainpane.add(stdoptions) mainpane.add(buttons) def show(self): self.mainframe.setLocation(100, 100) self.mainframe.pack() self.mainframe.show() #actionlisteners def changegw(self, ae): self.buildgwoptions(self.gwlist.getSelectedItem()) self.mainframe.pack() self.mainframe.show() def addaccount(self, ae): gwselection = self.gwlist.getSelectedItem() gw = self.gateways[gwselection] name = gw["ident"].text passwd = gw["passwd"].text host = gw["host"].text port = int(gw["port"].text) autologin = self.autologin.isSelected() acctname = self.acctname.text if gwselection == "Twisted": sname = gw["service"].text perspective = gw["persp"].text self.am.addAccount( PBAccount(acctname, autologin, name, passwd, host, port, [[stype, sname, perspective]])) elif gwselection == "AIM": self.am.addAccount( TOCAccount(acctname, autologin, name, passwd, host, port)) elif gwselection == "IRC": channels = gw["channels"].text self.am.addAccount( IRCAccount(acctname, autologin, name, passwd, host, port, channels)) self.amgui.update() print "Added new account" self.mainframe.dispose() def cancel(self, ae): print "Cancelling new account creation" self.mainframe.dispose()
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, IContextMenuFactory, IHttpRequestResponseWithMarkers, ITextEditor): def registerExtenderCallbacks(self, callbacks): self._callbacks = callbacks #Initialize callbacks to be used later self._helpers = callbacks.getHelpers() callbacks.setExtensionName("Trishul") self._log = ArrayList() #_log used to store our outputs for a URL, which is retrieved later by the tool self._lock = Lock() #Lock is used for locking threads while updating logs in order such that no multiple updates happen at once self.intercept = 0 self.FOUND = "Found" self.CHECK = "Possible! Check Manually" self.NOT_FOUND = "Not Found" #Static Values for output #Initialize GUI self.issuesTab() self.advisoryReqResp() self.configTab() self.tabsInit() self.definecallbacks() print("Thank You for Installing Trishul") return # #Initialize Issues Tab displaying the JTree # def issuesTab(self): self.root = DefaultMutableTreeNode('Issues') frame = JFrame("Issues Tree") self.tree = JTree(self.root) self.rowSelected = '' self.tree.addMouseListener(mouseclick(self)) self.issuepanel = JScrollPane() self.issuepanel.setPreferredSize(Dimension(300,450)) self.issuepanel.getViewport().setView((self.tree)) frame.add(self.issuepanel,BorderLayout.CENTER) # #Adding Issues to Issues TreePath # def addIssues(self, branch, branchData=None): if branchData == None: branch.add(DefaultMutableTreeNode('No valid data')) else: for item in branchData: branch.add(DefaultMutableTreeNode(item)) # #Initialize the Config Tab to modify tool settings # def configTab(self): Config = JLabel("Config") self.startButton = JToggleButton("Intercept Off", actionPerformed=self.startOrStop) self.startButton.setBounds(40, 30, 200, 30) self.autoScroll = JCheckBox("Auto Scroll") self.autoScroll.setBounds(40, 80, 200, 30) self.xsscheck = JCheckBox("Detect XSS") self.xsscheck.setSelected(True) self.xsscheck.setBounds(40, 110, 200, 30) self.sqlicheck = JCheckBox("Detect SQLi") self.sqlicheck.setSelected(True) self.sqlicheck.setBounds(40, 140, 200, 30) self.ssticheck = JCheckBox("Detect SSTI") self.ssticheck.setSelected(True) self.ssticheck.setBounds(40, 170, 200, 30) self.blindxss = JCheckBox("Blind XSS") self.blindxss.setBounds(40, 200, 200, 30) self.BlindXSSText = JTextArea("", 5, 30) scrollbxssText = JScrollPane(self.BlindXSSText) scrollbxssText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED) scrollbxssText.setBounds(40, 250, 400, 110) self.configtab = JPanel() self.configtab.setLayout(None) self.configtab.setBounds(0, 0, 300, 300) self.configtab.add(Config) self.configtab.add(self.startButton) self.configtab.add(self.autoScroll) self.configtab.add(self.xsscheck) self.configtab.add(self.sqlicheck) self.configtab.add(self.ssticheck) self.configtab.add(self.blindxss) self.configtab.add(scrollbxssText) # #Turn Intercept from Proxy on or off # def startOrStop(self, event): if self.startButton.getText() == "Intercept Off": self.startButton.setText("Intercept On") self.startButton.setSelected(True) self.intercept = 1 else: self.startButton.setText("Intercept Off") self.startButton.setSelected(False) self.intercept = 0 # #Intialize the Advisory, Request and Response Tabs # def advisoryReqResp(self): self.textfield = JEditorPane("text/html", "") self.kit = HTMLEditorKit() self.textfield.setEditorKit(self.kit) self.doc = self.textfield.getDocument() self.textfield.setEditable(0) self.advisorypanel = JScrollPane() self.advisorypanel.getVerticalScrollBar() self.advisorypanel.setPreferredSize(Dimension(300,450)) self.advisorypanel.getViewport().setView((self.textfield)) self.selectedreq = [] self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self._texteditor = self._callbacks.createTextEditor() self._texteditor.setEditable(False) # #Initialize Trishul Tabs # def tabsInit(self): self.logTable = Table(self) tableWidth = self.logTable.getPreferredSize().width self.logTable.getColumn("#").setPreferredWidth(Math.round(tableWidth / 50 * 0.1)) self.logTable.getColumn("Method").setPreferredWidth(Math.round(tableWidth / 50 * 3)) self.logTable.getColumn("URL").setPreferredWidth(Math.round(tableWidth / 50 * 40)) self.logTable.getColumn("Parameters").setPreferredWidth(Math.round(tableWidth / 50 * 1)) self.logTable.getColumn("XSS").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("SQLi").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("SSTI").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Request Time").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.tableSorter = TableRowSorter(self) self.logTable.setRowSorter(self.tableSorter) self._bottomsplit = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._bottomsplit.setDividerLocation(500) self.issuetab = JTabbedPane() self.issuetab.addTab("Config",self.configtab) self.issuetab.addTab("Issues",self.issuepanel) self._bottomsplit.setLeftComponent(self.issuetab) self.tabs = JTabbedPane() self.tabs.addTab("Advisory",self.advisorypanel) self.tabs.addTab("Request", self._requestViewer.getComponent()) self.tabs.addTab("Response", self._responseViewer.getComponent()) self.tabs.addTab("Highlighted Response", self._texteditor.getComponent()) self._bottomsplit.setRightComponent(self.tabs) self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT) self._splitpane.setDividerLocation(450) self._splitpane.setResizeWeight(1) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) self.scrollPane.getVerticalScrollBar().addAdjustmentListener(autoScrollListener(self)) self._splitpane.setRightComponent(self._bottomsplit) # #Initialize burp callbacks # def definecallbacks(self): self._callbacks.registerHttpListener(self) self._callbacks.customizeUiComponent(self._splitpane) self._callbacks.customizeUiComponent(self.logTable) self._callbacks.customizeUiComponent(self.scrollPane) self._callbacks.customizeUiComponent(self._bottomsplit) self._callbacks.registerContextMenuFactory(self) self._callbacks.addSuiteTab(self) # #Menu Item to send Request to Trishul # def createMenuItems(self, invocation): responses = invocation.getSelectedMessages() if responses > 0: ret = LinkedList() requestMenuItem = JMenuItem("Send request to Trishul") for response in responses: requestMenuItem.addActionListener(handleMenuItems(self,response, "request")) ret.add(requestMenuItem) return ret return None # #Highlighting Response # def markHttpMessage( self, requestResponse, responseMarkString ): responseMarkers = None if responseMarkString: response = requestResponse.getResponse() responseMarkBytes = self._helpers.stringToBytes( responseMarkString ) start = self._helpers.indexOf( response, responseMarkBytes, False, 0, len( response ) ) if -1 < start: responseMarkers = [ array( 'i',[ start, start + len( responseMarkBytes ) ] ) ] requestHighlights = [array( 'i',[ 0, 5 ] )] return self._callbacks.applyMarkers( requestResponse, requestHighlights, responseMarkers ) def getTabCaption(self): return "Trishul" def getUiComponent(self): return self._splitpane # #Table Model to display URL's and results based on the log size # def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 8 def getColumnName(self, columnIndex): data = ['#','Method', 'URL', 'Parameters', 'XSS', 'SQLi', "SSTI", "Request Time"] try: return data[columnIndex] except IndexError: return "" def getColumnClass(self, columnIndex): data = [Integer, String, String, Integer, String, String, String, String] try: return data[columnIndex] except IndexError: return "" #Get Data stored in log and display in the respective columns def getValueAt(self, rowIndex, columnIndex): logEntry = self._log.get(rowIndex) if columnIndex == 0: return rowIndex+1 if columnIndex == 1: return logEntry._method if columnIndex == 2: return logEntry._url.toString() if columnIndex == 3: return len(logEntry._parameter) if columnIndex == 4: return logEntry._XSSStatus if columnIndex == 5: return logEntry._SQLiStatus if columnIndex == 6: return logEntry._SSTIStatus if columnIndex == 7: return logEntry._req_time return "" def getHttpService(self): return self._currentlyDisplayedItem.getHttpService() def getRequest(self): return self._currentlyDisplayedItem.getRequest() def getResponse(self): return self._currentlyDisplayedItem.getResponse() #For Intercepted requests perform tests in scope def processHttpMessage(self, toolFlag, messageIsRequest, messageInf): if self.intercept == 1: if toolFlag == self._callbacks.TOOL_PROXY: if not messageIsRequest: requestInfo = self._helpers.analyzeRequest(messageInf) requeststr = requestInfo.getUrl() parameters = requestInfo.getParameters() param_new = [p for p in parameters if p.getType() != 2] if len(param_new) != 0: if self._callbacks.isInScope(URL(str(requeststr))): start_new_thread(self.sendRequestToTrishul,(messageInf,)) return # #Main processing of Trishul # def sendRequestToTrishul(self,messageInfo): request = messageInfo.getRequest() req_time = datetime.datetime.today() requestURL = self._helpers.analyzeRequest(messageInfo).getUrl() messageInfo = self._callbacks.makeHttpRequest(self._helpers.buildHttpService(str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https"), request) resp_time = datetime.datetime.today() time_taken = (resp_time - req_time).total_seconds() response = messageInfo.getResponse() #initialozations of default value SQLiimp = self.NOT_FOUND SSTIimp = self.NOT_FOUND XSSimp = self.NOT_FOUND Comp_req = messageInfo requestInfo = self._helpers.analyzeRequest(messageInfo) self.content_resp = self._helpers.analyzeResponse(response) requestURL = requestInfo.getUrl() parameters = requestInfo.getParameters() requeststring = self._helpers.bytesToString(request) headers = requestInfo.getHeaders() #Used to obtain GET, POST and JSON parameters from burp api param_new = [p for p in parameters if p.getType() == 0 or p.getType() == 1 or p.getType() == 6] i = 0 xssflag=0 sqliflag=0 sstiflag=0 resultxss = [] resultsqli = [] resultssti = [] xssreqresp = [] sqlireqresp = [] sstireqresp = [] ssti_description = [] sqli_description = [] xss_description = [] for i in range(len(param_new)): name = param_new[i].getName() ptype = param_new[i].getType() param_value = param_new[i].getValue() #check XSS if ticked if self.xsscheck.isSelected(): score = 0 flag1 = 0 XSSimp = self.NOT_FOUND payload_array = ["<", ">", "\\\\'asd", "\\\\\"asd", "\\", "'\""] json_payload_array = ["<", ">", "\\\\'asd", "\\\"asd", "\\", "\'\\\""] payload_all = "" json_payload = "" rand_str = "testtest" for payload in payload_array: payload_all = payload_all+rand_str+payload payload_all = URLEncoder.encode(payload_all, "UTF-8") for payload in json_payload_array: json_payload = json_payload+rand_str+payload json_payload = URLEncoder.encode(json_payload, "UTF-8") if ptype == 0 or ptype == 1: new_paramters_value = self._helpers.buildParameter(name, payload_all, ptype) updated_request = self._helpers.updateParameter(request, new_paramters_value) else: jsonreq = re.search(r"\s([{\[].*?[}\]])$", requeststring).group(1) new = jsonreq.split(name+"\":",1)[1] if new.startswith('\"'): newjsonreq = jsonreq.replace(name+"\":\""+param_value,name+"\":\""+json_payload) else: newjsonreq = jsonreq.replace(name+"\":"+param_value,name+"\":\""+json_payload+"\"") updated_request = self._helpers.buildHttpMessage(headers, newjsonreq) attack = self.makeRequest(Comp_req, updated_request) response = attack.getResponse() response_str = self._helpers.bytesToString(response) xssreqresp.append(attack) if_found_payload = "" non_encoded_symbols = "" for check_payload in payload_array: if_found_payload = rand_str+check_payload if if_found_payload in response_str: non_encoded_symbols = non_encoded_symbols+"<br>"+check_payload.replace('<', '<') score = score+1 flag1 = 1 if score > 2: XSSimp = self.CHECK if score > 3: XSSimp = self.FOUND xssflag = self.checkBetterScore(score,xssflag) if non_encoded_symbols == " \\\\'asd": XSSimp = self.NOT_FOUND if non_encoded_symbols != '': xss_description.append("The Payload <b>" + payload_all.replace('<', '<') + "</b> was passed in the request for the paramater <b>" + self._helpers.urlDecode(name) + "</b>. Some Tags were observed in the output unfiltered. A payload can be generated with the observed tags.<br>Symbols not encoded for parameter <b>" + name + "</b>: " + non_encoded_symbols) else: xss_description.append("") else: XSSimp = "Disabled" resultxss.append(XSSimp) if self.sqlicheck.isSelected(): SQLiimp = self.NOT_FOUND score = 0 value = "%27and%28select%2afrom%28select%28sleep%285%29%29%29a%29--" orig_time = datetime.datetime.today() if ptype == 0 or ptype == 1: new_paramters_value = self._helpers.buildParameter(name, value, ptype) updated_request = self._helpers.updateParameter(request, new_paramters_value) else: jsonreq = re.search(r"\s([{\[].*?[}\]])$", requeststring).group(1) new = jsonreq.split(name+"\":",1)[1] if new.startswith('\"'): newjsonreq = jsonreq.replace(name+"\":\""+param_value,name+"\":\""+value) else: newjsonreq = jsonreq.replace(name+"\":"+param_value,name+"\":\""+value+"\"") updated_request = self._helpers.buildHttpMessage(headers, newjsonreq) attack1 = self.makeRequest(Comp_req, updated_request) response1 = attack1.getResponse() new_time = datetime.datetime.today() response_str1 = self._helpers.bytesToString(response1) sqlireqresp.append(attack1) diff = (new_time - orig_time).total_seconds() if (diff - time_taken) > 3: score = 4 self.error_array = ["check the manual that corresponds to your", "You have an error", "syntax error", "SQL syntax", "SQL statement", "ERROR:", "Error:", "MySQL","Warning:","mysql_fetch_array()"] found_text = "" for error in self.error_array: if error in response_str1: found_text = found_text + error score = score + 1 if score > 1: SQLiimp = self.CHECK if score > 2: SQLiimp = self.FOUND sqliflag = self.checkBetterScore(score,sqliflag) if found_text != '': sqli_description.append("The payload <b>"+self._helpers.urlDecode(value)+"</b> was passed in the request for parameter <b>"+self._helpers.urlDecode(name)+"</b>. Some errors were generated in the response which confirms that there is an Error based SQLi. Please check the request and response for this parameter") elif (diff - time_taken) > 3: sqli_description.append("The payload <b>"+self._helpers.urlDecode(value)+"</b> was passed in the request for parameter <b>"+self._helpers.urlDecode(name)+"</b>. The response was in a delay of <b>"+str(diff)+"</b> seconds as compared to original <b>"+str(time_taken)+"</b> seconds. This indicates that there is a time based SQLi. Please check the request and response for this parameter") else: sqli_description.append("") else: SQLiimp = "Disabled" resultsqli.append(SQLiimp) if self.ssticheck.isSelected(): score = 0 SSTIimp = self.NOT_FOUND payload_array = ["${123*456}", "<%=123*567%>", "{{123*678}}"] json_payload_array = ["$\{123*456\}", "<%=123*567%>", "\{\{123*678\}\}"] payload_all = "" rand_str = "jjjjjjj" json_payload = "" for payload in payload_array: payload_all = payload_all+rand_str+payload for payload in json_payload_array: json_payload = json_payload+rand_str+payload payload_all = URLEncoder.encode(payload_all, "UTF-8") json_payload = URLEncoder.encode(json_payload, "UTF-8") if ptype == 0 or ptype == 1: new_paramters_value = self._helpers.buildParameter(name, payload_all, ptype) updated_request = self._helpers.updateParameter(request, new_paramters_value) else: jsonreq = re.search(r"\s([{\[].*?[}\]])$", requeststring).group(1) new = jsonreq.split(name+"\":",1)[1] if new.startswith('\"'): newjsonreq = jsonreq.replace(name+"\":\""+param_value,name+"\":\""+json_payload) else: newjsonreq = jsonreq.replace(name+"\":"+param_value,name+"\":\""+json_payload+"\"") updated_request = self._helpers.buildHttpMessage(headers, newjsonreq) attack = self.makeRequest(Comp_req, updated_request) response = attack.getResponse() response_str = self._helpers.bytesToString(response) self.expected_output = ["56088","69741","83394","3885","777777777777777"] for output in self.expected_output: if_found_payload = rand_str+output if if_found_payload in response_str: if output == self.expected_output[0]: sstireqresp.append(attack) ssti_description.append("Parameter <b>" + self._helpers.urlDecode(name) + "</b> is using <b>Java</b> Template<br>The value <b>" + payload_new + "</b> was passed which gave result as <b>56088</b>") score = 2 if output == self.expected_output[1]: sstireqresp.append(attack) ssti_description.append("Parameter <b>" + self._helpers.urlDecode(name) + "</b> is using <b>Ruby</b> Template<br>The value <b>" + payload_new + "</b> was passed which gave result as <b>69741</b>") score = 2 if output == self.expected_output[2]: payload_new = "{{5*'777'}}" json_payload_ssti = "\{\{5*'777'\}\}" payload = URLEncoder.encode("{{5*'777'}}", "UTF-8") json_ssti = URLEncoder.encode("\{\{5*'777'\}\}", "UTF-8") if ptype == 0 or ptype == 1: new_paramters = self._helpers.buildParameter(name, payload, ptype) ssti_updated_request = self._helpers.updateParameter(request, new_paramters) else: jsonreq = re.search(r"\s([{\[].*?[}\]])$", requeststring).group(1) new = jsonreq.split(name+"\":",1)[1] if new.startswith('\"'): newjsonreq = jsonreq.replace(name+"\":\""+param_value,name+"\":\""+json_ssti) else: newjsonreq = jsonreq.replace(name+"\":"+param_value,name+"\":\""+json_ssti+"\"") ssti_updated_request = self._helpers.buildHttpMessage(headers, newjsonreq) self.ssti_attack = self.makeRequest(Comp_req, ssti_updated_request) ssti_response = self.ssti_attack.getResponse() ssti_response_str = self._helpers.bytesToString(ssti_response) if self.expected_output[3] in ssti_response_str: sstireqresp.append(self.ssti_attack) ssti_description.append("Parameter <b>" + self._helpers.urlDecode(name) + "</b> is using <b>Twig</b> Template<br>The value <b>" + payload_new + "</b> was passed which gave result as <b>3885</b>") score = 2 elif self.expected_output[4] in ssti_response_str: sstireqresp.append(self.ssti_attack) self.responseMarkString = "777777777777777" ssti_description.append("Parameter <b>" + self._helpers.urlDecode(name) + "</b> is using <b>Jinja2</b> Template<br>The value <b>" + payload_new + "</b> was passed which gave result as <b>777777777777777</b>") score = 2 if score > 0: SSTIimp = self.CHECK if score > 1: SSTIimp = self.FOUND sstiflag = self.checkBetterScore(score,sstiflag) else: SSTIimp = "Disabled" resultssti.append(SSTIimp) if self.blindxss.isSelected(): blindxss_value = self.BlindXSSText.getText() if ptype == 0 or ptype == 1: new_paramters_value = self._helpers.buildParameter(name, blindxss_value, ptype) updated_request = self._helpers.updateParameter(request, new_paramters_value) else: jsonreq = re.search(r"\s([{\[].*?[}\]])$", requeststring).group(1) new = jsonreq.split(name+"\":",1)[1] if new.startswith('\"'): newjsonreq = jsonreq.replace(name+"\":\""+param_value,name+"\":\""+blindxss_value) else: newjsonreq = jsonreq.replace(name+"\":"+param_value,name+"\":\""+blindxss_value+"\"") updated_request = self._helpers.buildHttpMessage(headers, newjsonreq) attack = self.makeRequest(Comp_req, updated_request) if XSSimp != "Disabled": if xssflag > 3: XSSimp = self.FOUND elif xssflag > 2: XSSimp = self.CHECK else: XSSimp = self.NOT_FOUND if SSTIimp != "Disabled": if sstiflag > 1: SSTIimp = self.FOUND elif sstiflag > 0: SSTIimp = self.CHECK else: SSTIimp = self.NOT_FOUND if SQLiimp != "Disabled": if sqliflag > 3: SQLiimp = self.FOUND elif sqliflag > 2: SQLiimp = self.CHECK else: SQLiimp = self.NOT_FOUND self.addToLog(messageInfo, XSSimp, SQLiimp, SSTIimp, param_new, resultxss, resultsqli, resultssti, xssreqresp, sqlireqresp, sstireqresp , xss_description, sqli_description, ssti_description, req_time.strftime('%H:%M:%S %m/%d/%y')) # #Function used to check if the score originally and mentioned is better # def checkBetterScore(self, score, ogscore): if score > ogscore: ogscore = score return ogscore def makeRequest(self, messageInfo, message): request = messageInfo.getRequest() requestURL = self._helpers.analyzeRequest(messageInfo).getUrl() return self._callbacks.makeHttpRequest(self._helpers.buildHttpService(str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https"), message) def addToLog(self, messageInfo, XSSimp, SQLiimp, SSTIimp, parameters, resultxss, resultsqli, resultssti, xssreqresp, sqlireqresp, sstireqresp, xss_description, sqli_description, ssti_description, req_time): requestInfo = self._helpers.analyzeRequest(messageInfo) method = requestInfo.getMethod() self._lock.acquire() row = self._log.size() self._log.add(LogEntry(self._callbacks.saveBuffersToTempFiles(messageInfo), requestInfo.getUrl(),method,XSSimp,SQLiimp,SSTIimp,req_time, parameters,resultxss, resultsqli, resultssti, xssreqresp, sqlireqresp, sstireqresp, xss_description, sqli_description, ssti_description)) # same requests not include again. SwingUtilities.invokeLater(UpdateTableEDT(self,"insert",row,row)) self._lock.release()
class WorkHelper(JFrame): def __init__(self): super(WorkHelper, self).__init__() self.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard() ############################################################# # Layout: layout = GroupLayout(self.getContentPane()) self.getContentPane().setLayout(layout) layout.setAutoCreateGaps(True) layout.setAutoCreateContainerGaps(True) ############################################################# ############################################################# # Frame Area: Larea1 = JLabel("InputArea:") Sarea1 = JScrollPane() self.area1 = JTextArea() self.area1.setToolTipText("Input Area") self.area1.setEditable(True) self.area1.setBorder(BorderFactory.createLineBorder(Color.gray)) Sarea1.setPreferredSize(Dimension(300,100)) Sarea1.getViewport().setView((self.area1)) bClear = JButton("Clear", actionPerformed=self.bClear) bClear.setToolTipText("Clears the text form both Input and Output text Areas") bCopyToInput = JButton("Copy to Input", actionPerformed=self.bCopyToInput) bCopyToInput.setToolTipText("Copy the text from the Output Area to the Input Area for further Operations") self.cCtClipB = JCheckBox("Auto-Copy"); self.cCtClipB.setToolTipText("When 'Checked' after the Categories are created they will added to the clipboard") self.cCtClipB.setSelected(1) Larea2 = JLabel("OutputArea:") Sarea2 = JScrollPane() self.area2 = JTextArea() self.area2.setToolTipText("Output Area") self.area2.setEditable(False) self.area2.setBorder(BorderFactory.createLineBorder(Color.gray)) Sarea2.setPreferredSize(Dimension(300,100)) Sarea2.getViewport().setView((self.area2)) ############################################################# # Tabbed Area: tabPane = JTabbedPane(JTabbedPane.TOP) self.getContentPane().add(tabPane) ##################################################### # Text Edit pane panel_TEdit = JPanel() layout2 = GroupLayout(panel_TEdit) layout2.setAutoCreateGaps(True) layout2.setAutoCreateContainerGaps(True) panel_TEdit.setLayout(layout2) bRemoveNBSP_L = JButton("Clean LText", actionPerformed=self.bRemoveNBSP_L) bRemoveNBSP_L.setToolTipText("Removes Spaces, Tabs from the start of every text line from the input Area") bRemoveNBSP_R = JButton("Clean RText", actionPerformed=self.bRemoveNBSP_R) bRemoveNBSP_R.setToolTipText("Removes Spaces, Tabs from the end of every text line from the input Area") self.ReplaceThis = JTextField() self.ReplaceThis = JTextField(maximumSize=Dimension(120,25)) self.ReplaceThis.setToolTipText("Text to be replaced") self.ReplaceThat = JTextField() self.ReplaceThat = JTextField(maximumSize=Dimension(120,25)) self.ReplaceThat.setToolTipText("Text to be placed") bSandReplace = JButton("Replace Text", actionPerformed=self.bSandReplace) bSandReplace.setToolTipText("Replace the text from This with Text from That in the Text from the Input Area and displays it in the Output Area") bRemNumbers = JButton("Rem Numbers", actionPerformed=self.RemNumbers) bRemNumbers.setToolTipText("Removes numbers from the start of every line") ##################################################### # Dimension pane panel_Dimensions = JPanel() layout3 = GroupLayout(panel_Dimensions) layout3.setAutoCreateGaps(True) layout3.setAutoCreateContainerGaps(True) panel_Dimensions.setLayout(layout3) self.cCurly = JCheckBox("Curly"); self.cCurly.setToolTipText("When 'Checked' Curly Brackets will surround the Categories") self.cCurly.setSelected(1) self.cSemiC = JCheckBox("SemiColumn"); self.cSemiC.setToolTipText("When 'Checked' after the Categories are created at the end will be a semicolomn") self.cSemiC.setSelected(1) self.iStart = JTextField(maximumSize=Dimension(40,25)) self.iStart.setToolTipText("The Start Index for the Making of the Categories") self.RThis = JTextField() self.RThis = JTextField(maximumSize=Dimension(120,25)) self.RThis.setToolTipText("The Starting Index used in creating the Categorical") self.RThat = JTextField() self.RThat = JTextField(maximumSize=Dimension(120,25)) self.RThat.setToolTipText("The Finish Index used in creating the Categorical") optioncCategories = JLabel("Options:") bcCat = JButton("CreatCateg", actionPerformed=self.bcCat) bcCat.setToolTipText("Create a categorical form starting C_Index to finish C_Index; Use the text boxes to define the indexes") bM_Categories = JButton("Categories", actionPerformed=self.mCategories) bM_Categories.setToolTipText("Make Categories using the lines from the Input Area. Use it to define Categorical questions.") ##################################################### # ConfirmIt pane panel_ConfirmIt = JPanel() layout4 = GroupLayout(panel_ConfirmIt) layout4.setAutoCreateGaps(True) layout4.setAutoCreateContainerGaps(True) panel_ConfirmIt.setLayout(layout4) self.PID = JTextField() self.PID = JTextField(maximumSize=Dimension(120,25)) self.PID.setToolTipText("The PID number used for creating links with PID and ids from every line of the Input Area") bClinks = JButton("Create Links", actionPerformed=self.bClinks) bClinks.setToolTipText("Create links for a project using PID and ID, ID`s are read from every line of the Input Area") bClinksNA = JButton("Create Links NA ", actionPerformed=self.bClinksNA) bClinksNA.setToolTipText("Create links for a project using PID and ID`s from the standard sample test for US") bClinksCA = JButton("Create Links CA", actionPerformed=self.bClinksCA) bClinksCA.setToolTipText("Create links for a project using PID and ID`s from the standard sample test for CA") self.Width = JTextField() self.Width = JTextField(maximumSize=Dimension(120,25)) self.Width.setToolTipText("The Width used in creating the DIV html tag, note the dimension used is in px") baddDIVt = JButton("Add DIV tag", actionPerformed=self.baddDIVt) baddDIVt.setToolTipText("Create a DIV tag for every line in the Input Area") ##################################################### # Statistics pane panel_Statistics = JPanel() layout5 = GroupLayout(panel_Statistics) layout5.setAutoCreateGaps(True) layout5.setAutoCreateContainerGaps(True) panel_Statistics.setLayout(layout5) ##################################################### # TimeTraking pane panel_TimeTraking = JPanel() layout6 = GroupLayout(panel_TimeTraking) layout6.setAutoCreateGaps(True) layout6.setAutoCreateContainerGaps(True) panel_TimeTraking.setLayout(layout6) ##################################################### # Tabbed Area Tabs tabPane.addTab("Text Edit", panel_TEdit) tabPane.addTab("Dimensions", panel_Dimensions) tabPane.addTab("ConfirmIt", panel_ConfirmIt) tabPane.addTab("Statistics", panel_Statistics) tabPane.addTab("TimeTraking", panel_TimeTraking) ############################################################# ############################################################# # Aplication Layouts: 2 groups one Horizontal and one Vertical ############################################################# # Frame Layout: 2 groups one Horizontal and one Vertical layout.setHorizontalGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup() .addComponent(Larea1) .addComponent(Sarea1) .addComponent(Sarea2) .addGroup(layout.createSequentialGroup() .addComponent(bCopyToInput) .addComponent(bClear) .addComponent(self.cCtClipB)) .addComponent(Larea2)) .addGroup(layout.createParallelGroup() .addComponent(tabPane)) ) layout.setVerticalGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup() .addGroup(layout.createSequentialGroup() .addComponent(Larea1) .addComponent(Sarea1) .addGroup(layout.createParallelGroup() .addComponent(bCopyToInput) .addComponent(bClear) .addComponent(self.cCtClipB) ) .addComponent(Larea2) .addComponent(Sarea2)) .addGroup(layout.createSequentialGroup() .addComponent(tabPane)) ) ) ############################################################# # TEdit Layout: 2 groups one Horizontal and one Vertical layout2.setHorizontalGroup(layout2.createSequentialGroup() .addGroup(layout2.createParallelGroup() .addGroup(layout2.createSequentialGroup() .addComponent(bRemNumbers) .addComponent(bRemoveNBSP_L) .addComponent(bRemoveNBSP_R)) .addGroup(layout2.createSequentialGroup() .addComponent(bSandReplace) .addComponent(self.ReplaceThis) .addComponent(self.ReplaceThat)) )) layout2.setVerticalGroup(layout2.createSequentialGroup() .addGroup(layout2.createParallelGroup() .addComponent(bRemNumbers) .addComponent(bRemoveNBSP_L) .addComponent(bRemoveNBSP_R)) .addGroup(layout2.createParallelGroup() .addComponent(bSandReplace) .addComponent(self.ReplaceThis) .addComponent(self.ReplaceThat)) ) ############################################################# # Dimensions Layout: 2 groups one Horizontal and one Vertical layout3.setHorizontalGroup(layout3.createSequentialGroup() .addGroup(layout3.createParallelGroup() .addGroup(layout3.createSequentialGroup() .addComponent(bM_Categories) .addComponent(self.iStart)) .addGroup(layout3.createSequentialGroup() .addComponent(optioncCategories) .addComponent(self.cCurly) .addComponent(self.cSemiC) ) .addGroup(layout3.createSequentialGroup() .addComponent(bcCat) .addComponent(self.RThis) .addComponent(self.RThat)) .addGroup(layout3.createSequentialGroup() ) ) ) layout3.setVerticalGroup(layout3.createSequentialGroup() .addGroup(layout3.createSequentialGroup() .addGroup(layout3.createParallelGroup() .addComponent(bM_Categories) .addComponent(self.iStart)) .addGroup(layout3.createParallelGroup() .addComponent(bcCat) .addComponent(self.RThis) .addComponent(self.RThat)) .addGroup(layout3.createParallelGroup() .addGroup(layout3.createParallelGroup() .addComponent(optioncCategories) .addComponent(self.cCurly) .addComponent(self.cSemiC) ) ) ) ) ############################################################# # ConfimIT Layout: 2 groups one Horizontal and one Vertical layout4.setHorizontalGroup(layout4.createSequentialGroup() .addGroup(layout4.createParallelGroup() .addGroup(layout4.createSequentialGroup() .addComponent(bClinks) .addComponent(self.PID) ) .addGroup(layout4.createSequentialGroup() .addComponent(bClinksNA) .addComponent(bClinksCA) ) .addGroup(layout4.createSequentialGroup() .addComponent(baddDIVt) .addComponent(self.Width) ) )) layout4.setVerticalGroup(layout4.createSequentialGroup() .addGroup(layout4.createSequentialGroup() .addGroup(layout4.createParallelGroup() .addComponent(bClinks) .addComponent(self.PID)) .addGroup(layout4.createParallelGroup() .addComponent(bClinksNA) .addComponent(bClinksCA) ) .addGroup(layout4.createParallelGroup() .addComponent(baddDIVt) .addComponent(self.Width) ) )) #layout2.linkSize(SwingConstants.HORIZONTAL, [self.cCurly,bM_Categories]) #layout.linkSize(SwingConstants.HORIZONTAL, [ok, bCopyToInput, close, bM_Categories]) #layout3.linkSize(SwingConstants.HORIZONTAL, [self.RThis,self.RThat,bRemoveNBSP_L,bRemoveNBSP_R,bM_Categories,bSandReplace,bcCat]) ############################################################# ############################################################# # Aplication Settings self.pack() #self.setPreferredSize(Dimension(1000, 1000)) self.setTitle("Workhelper") self.setSize(800, 500) self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) self.setLocationRelativeTo(None) self.setVisible(True) ############################################################# ############################################################# # WorkHelper class methods: def onQuit(self, e): "@sig public void setExpression(java.lang.String e)" os.system.exit(0) # def addToClipBoard(self, text): # "@sig public void setExpression(java.lang.String text)" # command = 'echo ' + text.strip() + '| clip' # os.system(command) # brute method for pasting into clipboard on windows def mCategories(self, e): "@sig public void setExpression(java.lang.String e)" """ Takes every line of text form the Input Area and by using a string composition it creates the output in the SPSS dimension categories format. """ try: StartIndex = int(self.iStart.getText()) except ValueError: StartIndex=1 text=self.area1.getText().rstrip() counter=StartIndex lastindex=0 textO="" for i in range(0,len(text)): if text[i]=='\n': textO=textO+("_"+str(counter)+' "'+text[lastindex:i]+'",\n') lastindex=i+1 counter=counter+1 if len(text[lastindex:len(text)])>0: textO=textO+("_"+str(counter)+' "'+text[lastindex:len(text)]+'"') if len(textO)>0: if self.cCurly.isSelected(): textO = "{\n"+ textO + "\n}" if self.cSemiC.isSelected(): textO = textO + ";" self.copyToClipboard(textO) self.area2.setText(textO) def copyToClipboard(self, text): if self.cCtClipB.isSelected(): stringSelection = StringSelection(text) self.clipboard.setContents(stringSelection, None) def bCopyToInput(self, e): "@sig public void setExpression(java.lang.String e)" """Copy the Text from the Output Area to the input Area for further operations""" self.area1.setText(self.area2.getText()) def bRemoveNBSP_L(self, e): "@sig public void setExpression(java.lang.String e)" text=self.area1.getText().rstrip() textO="" lastindex=0 for i in range(0,len(text)): if text[i] == '\n': textO = textO+text[lastindex:i].lstrip()+"\n" lastindex=i+1 #print(text[0:i].lstrip()+'\n') if len(text[lastindex:len(text)])>0: textO=textO+text[lastindex:len(text)].lstrip() self.area2.setText(textO) def bRemoveNBSP_R(self, e): "@sig public void setExpression(java.lang.String e)" text=self.area1.getText().rstrip() textO="" lastindex=0 for i in range(0,len(text)): if text[i] == '\n': textO = textO+text[lastindex:i].rstrip()+"\n" lastindex=i+1 #print(text[0:i].lstrip()+'\n') if len(text[lastindex:len(text)])>0: textO=textO+text[lastindex:len(text)].rstrip() self.area2.setText(textO) def bClear(self, e): "@sig public void setExpression(java.lang.String e)" self.area1.setText("") self.area2.setText("") def bcCat(self, e): "@sig public void setExpression(java.lang.String e)" try: StartIndex = int(self.RThis.getText()) except ValueError: StartIndex=1 try: FinishIndex = int(self.RThat.getText()) except ValueError: FinishIndex=1 cCats="" for i in range(StartIndex,FinishIndex+1): if i<>FinishIndex: cCats=cCats+"_"+str(i)+"," else: cCats=cCats+"_"+str(i) if StartIndex<FinishIndex: cCats="{"+cCats+"}" self.copyToClipboard(cCats) self.area2.setText(cCats) def bSandReplace(self, e): self.area2.setText(self.area1.getText().replace(self.ReplaceThis.getText(),self.ReplaceThat.getText())) self.copyToClipboard(self.area2.getText()) ############################################################# # Confirmit def bClinks(self, e): text=self.area1.getText().rstrip() lastindex=0 textO="" for i in range(0,len(text)): if text[i]=='\n': textO=textO+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+text[lastindex:i]+'\n' lastindex=i+1 if len(text[lastindex:len(text)])>0: textO=textO+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+text[lastindex:len(text)] self.copyToClipboard(textO) self.area2.setText(textO) def bClinksNA(self, e): output="" for i in range (1,201): if i<10: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'US9900'+str(i)+'\n' else: if i<100: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'US990'+str(i)+'\n' else: if i==200: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'US99'+str(i) else: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'US99'+str(i)+'\n' self.area2.setText(output) self.copyToClipboard(self.area2.getText()) def bClinksCA(self, e): output="" for i in range (1,201): if i<10: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'CA9900'+str(i)+'\n' else: if i<100: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'CA990'+str(i)+'\n' else: if i==200: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'CA99'+str(i) else: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'CA99'+str(i)+'\n' self.area2.setText(output) self.copyToClipboard(self.area2.getText()) def baddDIVt(self, e): try: Width = int(self.Width.getText()) except ValueError: Width=1 text=self.area1.getText().rstrip() lastindex=0 textO="" for i in range(0,len(text)): if text[i]=='\n': textO=textO+'<div style="width:'+str(Width)+'px">'+text[lastindex:i]+'</div>'+'\n' lastindex=i+1 if len(text[lastindex:len(text)])>0: textO=textO+'<div style="width:'+str(Width)+'px">'+text[lastindex:len(text)]+'</div>' self.copyToClipboard(textO) self.area2.setText(textO) def RemNumbers(self, e): text=self.area1.getText().rstrip() lastindex=0 textO="" for i in range(0,len(text)): if text[i]=='\n': textO=textO+text[lastindex:i].lstrip('1234567890')+'\n' lastindex=i+1 if len(text[lastindex:len(text)])>0: textO=textO+text[lastindex:len(text)].lstrip('1234567890') self.copyToClipboard(textO) self.area2.setText(textO)
class StackOverlay: def __init__(self): self.frame = None self.overlayColorPreviewLabel = None self.showStackOverlayWindow() self.overlayColor = None def onQuit(self, e): print "Exiting..." self.frame.dispose() def showColorChooser(self, e): colorChooser = JColorChooser() self.overlayColor = colorChooser.showDialog(self.frame, "Choose color", Color.red) self.overlayColorPreviewLabel.setBackground(self.overlayColor) def showStackOverlayWindow(self): all = JPanel() all.setLayout(MigLayout()) self.imageIDs = WindowManager.getIDList() self.imageNames = [] if self.imageIDs is None: IJ.error("No open images", "Stack Overlay requires at least one image to be already open.") return for i in self.imageIDs: self.imageNames.append(WindowManager.getImage(i).getTitle()) self.baseImageBox = JComboBox(self.imageNames) baseImageBoxLabel = JLabel("Base image") self.baseImageBox.setSelectedIndex(0) all.add(baseImageBoxLabel) all.add(self.baseImageBox, "wrap") self.overlayImageBox = JComboBox(self.imageNames) overlayImageBoxLabel = JLabel("Overlay image") if len(self.imageNames) > 1: self.overlayImageBox.setSelectedIndex(1) all.add(overlayImageBoxLabel) all.add(self.overlayImageBox, "wrap") all.add(JSeparator(SwingConstants.HORIZONTAL), "span, wrap") overlayStyleFrame = JPanel() overlayStyleFrame.setLayout(MigLayout()) overlayStyleFrame.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Overlay Style"), BorderFactory.createEmptyBorder(5,5,5,5))) colorLabel = JLabel("Overlay color") self.overlayColorPreviewLabel = JLabel(" ") self.overlayColorPreviewLabel.setBorder(BorderFactory.createEmptyBorder(0,0,1,0)) self.overlayColorPreviewLabel.setOpaque(True) self.overlayColorPreviewLabel.setBackground(Color.red) self.overlayColor = Color.red colorPicker = JColorChooser() colorPicker.setPreviewPanel(self.overlayColorPreviewLabel) colorButton = JButton("Select color...", actionPerformed=self.showColorChooser) opacityLabel = JLabel("Overlay opacity (%)") opacitySpinnerModel = SpinnerNumberModel(100, 0, 100, 1) self.opacitySpinner = JSpinner(opacitySpinnerModel) overlayStyleFrame.add(colorLabel) overlayStyleFrame.add(self.overlayColorPreviewLabel) overlayStyleFrame.add(colorButton, "wrap") overlayStyleFrame.add(opacityLabel) overlayStyleFrame.add(self.opacitySpinner, "wrap") all.add(overlayStyleFrame, "span, wrap") self.virtualStackCheckbox = JCheckBox("Use Virtual Stack", True) all.add(self.virtualStackCheckbox, "span, wrap") # TODO: add non-thermonuclear cancel button functionality overlayCancelButton = JButton("Cancel", actionPerformed=self.onQuit) overlayStartButton = JButton("Overlay images", actionPerformed=self.overlayImages) all.add(overlayCancelButton, "gapleft push") all.add(overlayStartButton, "gapleft push") self.frame = JFrame("Stack Overlay") self.frame.getContentPane().add(JScrollPane(all)) self.frame.pack() self.frame.setLocationRelativeTo(None) self.frame.setVisible(True) def overlayImages(self, e): impBase = WindowManager.getImage(self.imageIDs[self.baseImageBox.getSelectedIndex()]) refBase = impBase.getStack().getProcessor(1) impOverlay = WindowManager.getImage(self.imageIDs[self.overlayImageBox.getSelectedIndex()]) refOverlay = impOverlay.getStack().getProcessor(1) print "Overlaying for stack sizes " + str(impBase.getStackSize()) + "/" + str(impOverlay.getStackSize()) + "..." stack = None if self.virtualStackCheckbox.isSelected(): stack = OverlayVirtualStack() stack.overlayOpacity = float(self.opacitySpinner.getValue())/100.0 stack.overlayColor = AWTColorToArray(self.overlayColorPreviewLabel.getBackground()) stack.base = impBase stack.overlay = impOverlay ImagePlus("Stack Overlay from " + self.imageNames[self.baseImageBox.getSelectedIndex()] + " and " + self.imageNames[self.overlayImageBox.getSelectedIndex()], stack).show() else: IJ.error("Not implemented yet", "Using normal stacks is not implemented yet. Please use the Virtual Stack option.")
class PreferencesFrame(JFrame, ActionListener, WindowListener, ItemListener, HyperlinkListener): """Dialog with preferences """ def __init__(self, parent, title, app): from javax.swing import JCheckBox, JRadioButton, ButtonGroup self.app = app border = BorderFactory.createEmptyBorder(5, 7, 5, 7) self.getContentPane().setBorder(border) self.getContentPane().setLayout(BorderLayout(0, 5)) self.tabbedPane = JTabbedPane() #1 Tab: general panel1 = JPanel() panel1.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7)) panel1.setLayout(BoxLayout(panel1, BoxLayout.PAGE_AXIS)) #Checkbutton to enable/disable update check when script starts self.updateCBtn = JCheckBox(self.app.strings.getString("updateCBtn")) self.updateCBtn.setToolTipText( self.app.strings.getString("updateCBtn_tooltip")) #Download tools downloadBtn = JButton(self.app.strings.getString("updatesBtn"), ImageProvider.get("dialogs", "refresh"), actionPerformed=self.on_downloadBtn_clicked) downloadBtn.setToolTipText( self.app.strings.getString("updatesBtn_tooltip")) #Checkbuttons for enabling/disabling tools toolsPanel = JPanel(BorderLayout(0, 5)) title = self.app.strings.getString("enable_disable_tools") toolsPanel.setBorder(BorderFactory.createTitledBorder(title)) infoLbl = JLabel(self.app.strings.getString("JOSM_restart_warning")) infoLbl.setFont(infoLbl.getFont().deriveFont(Font.ITALIC)) toolsPanel.add(infoLbl, BorderLayout.PAGE_START) toolsStatusPane = JPanel(GridLayout(len(self.app.realTools), 0)) self.toolsCBtns = [] for tool in self.app.realTools: toolCBtn = JCheckBox() toolCBtn.addItemListener(self) toolLbl = JLabel(tool.title, tool.bigIcon, JLabel.LEFT) self.toolsCBtns.append(toolCBtn) toolPane = JPanel() toolPane.setLayout(BoxLayout(toolPane, BoxLayout.X_AXIS)) toolPane.add(toolCBtn) toolPane.add(toolLbl) toolsStatusPane.add(toolPane) toolsPanel.add(toolsStatusPane, BorderLayout.CENTER) #Radiobuttons for enabling/disabling layers when a new one #is added layersPanel = JPanel(GridLayout(0, 1)) title = self.app.strings.getString("errors_layers_manager") layersPanel.setBorder(BorderFactory.createTitledBorder(title)) errorLayersLbl = JLabel( self.app.strings.getString("errors_layers_info")) errorLayersLbl.setFont(errorLayersLbl.getFont().deriveFont( Font.ITALIC)) layersPanel.add(errorLayersLbl) self.layersRBtns = {} group = ButtonGroup() for mode in self.app.layersModes: layerRBtn = JRadioButton(self.app.strings.getString("%s" % mode)) group.add(layerRBtn) layersPanel.add(layerRBtn) self.layersRBtns[mode] = layerRBtn #Max number of errors text field self.maxErrorsNumberTextField = JTextField() self.maxErrorsNumberTextField.setToolTipText( self.app.strings.getString("maxErrorsNumberTextField_tooltip")) self.maxErrorsNumberTFieldDefaultBorder = self.maxErrorsNumberTextField.getBorder( ) self.maxErrorsNumberTextField.getDocument().addDocumentListener( ErrNumTextListener(self)) #layout self.updateCBtn.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(self.updateCBtn) panel1.add(Box.createRigidArea(Dimension(0, 15))) downloadBtn.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(downloadBtn) panel1.add(Box.createRigidArea(Dimension(0, 15))) toolsPanel.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(toolsPanel) panel1.add(Box.createRigidArea(Dimension(0, 15))) layersPanel.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(layersPanel) panel1.add(Box.createRigidArea(Dimension(0, 15))) maxErrP = JPanel(BorderLayout(5, 0)) maxErrP.add(JLabel(self.app.strings.getString("max_errors_number")), BorderLayout.LINE_START) maxErrP.add(self.maxErrorsNumberTextField, BorderLayout.CENTER) p = JPanel(BorderLayout()) p.add(maxErrP, BorderLayout.PAGE_START) p.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(p) self.tabbedPane.addTab(self.app.strings.getString("tab_1_title"), None, panel1, None) #2 Tab: favourite zones panel2 = JPanel(BorderLayout(5, 15)) panel2.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7)) #status topPanel = JPanel() topPanel.setLayout(BoxLayout(topPanel, BoxLayout.Y_AXIS)) infoPanel = HtmlPanel(self.app.strings.getString("fav_zones_info")) infoPanel.getEditorPane().addHyperlinkListener(self) infoPanel.setAlignmentX(Component.LEFT_ALIGNMENT) self.favZoneStatusCBtn = JCheckBox( self.app.strings.getString("activate_fav_area"), actionListener=self) self.favZoneStatusCBtn.setToolTipText( self.app.strings.getString("activate_fav_area_tooltip")) self.favZoneStatusCBtn.setAlignmentX(Component.LEFT_ALIGNMENT) topPanel.add(infoPanel) topPanel.add(Box.createRigidArea(Dimension(0, 10))) topPanel.add(self.favZoneStatusCBtn) #table self.zonesTable = JTable() tableSelectionModel = self.zonesTable.getSelectionModel() tableSelectionModel.addListSelectionListener(ZonesTableListener(self)) columns = [ "", self.app.strings.getString("Type"), self.app.strings.getString("Name") ] tableModel = ZonesTableModel([], columns) self.zonesTable.setModel(tableModel) self.scrollPane = JScrollPane(self.zonesTable) #map self.zonesMap = JMapViewer() self.zonesMap.setZoomContolsVisible(False) self.zonesMap.setMinimumSize(Dimension(100, 200)) #buttons self.removeBtn = JButton(self.app.strings.getString("Remove"), ImageProvider.get("dialogs", "delete"), actionPerformed=self.on_removeBtn_clicked) self.removeBtn.setToolTipText( self.app.strings.getString("remove_tooltip")) newBtn = JButton(self.app.strings.getString("New"), ImageProvider.get("dialogs", "add"), actionPerformed=self.on_newBtn_clicked) newBtn.setToolTipText(self.app.strings.getString("new_tooltip")) #layout panel2.add(topPanel, BorderLayout.PAGE_START) panel2.add(self.scrollPane, BorderLayout.LINE_START) panel2.add(self.zonesMap, BorderLayout.CENTER) self.buttonsPanel = JPanel() self.buttonsPanel.add(self.removeBtn) self.buttonsPanel.add(newBtn) panel2.add(self.buttonsPanel, BorderLayout.PAGE_END) self.tabbedPane.addTab(self.app.strings.getString("tab_2_title"), None, panel2, None) #3 Tab Tools options panel3 = JPanel() panel3.setLayout(BoxLayout(panel3, BoxLayout.Y_AXIS)) panel3.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7)) for tool in self.app.realTools: if hasattr(tool, 'prefs'): p = JPanel(FlowLayout(FlowLayout.LEFT)) p.setBorder(BorderFactory.createTitledBorder(tool.title)) p.add(tool.prefsGui) panel3.add(p) self.tabbedPane.addTab(self.app.strings.getString("tab_3_title"), None, panel3, None) self.add(self.tabbedPane, BorderLayout.CENTER) exitPanel = JPanel() saveBtn = JButton(self.app.strings.getString("OK"), ImageProvider.get("ok"), actionPerformed=self.on_saveBtn_clicked) cancelBtn = JButton(self.app.strings.getString("cancel"), ImageProvider.get("cancel"), actionPerformed=self.on_cancelBtn_clicked) saveBtn.setToolTipText(self.app.strings.getString("save_preferences")) saveBtn.setAlignmentX(0.5) exitPanel.add(saveBtn) exitPanel.add(cancelBtn) self.add(exitPanel, BorderLayout.PAGE_END) self.addWindowListener(self) self.pack() def windowClosing(self, windowEvent): self.on_cancelBtn_clicked() def hyperlinkUpdate(self, e): if e.getEventType() == HyperlinkEvent.EventType.ACTIVATED: OpenBrowser.displayUrl(e.getURL().toString()) def itemStateChanged(self, e): """A ttol has been activated/deactivated. Check if at least one tool is on. """ if all(not button.isSelected() for button in self.toolsCBtns): JOptionPane.showMessageDialog( Main.parent, self.app.strings.getString("tools_disabled_warning"), self.app.strings.getString("tools_disabled_warning_title"), JOptionPane.WARNING_MESSAGE) source = e.getItemSelectable() source.setSelected(True) def actionPerformed(self, e=None): """Enable/disable favourite zones panel """ for container in (self.scrollPane, self.buttonsPanel): self.enableComponents(container, self.favZoneStatusCBtn.isSelected()) if self.favZoneStatusCBtn.isSelected(): self.check_removeBtn_status() def enableComponents(self, container, enable): components = container.getComponents() for component in components: component.setEnabled(enable) if isinstance(component, Container): self.enableComponents(component, enable) def on_downloadBtn_clicked(self, e): update_checker.Updater(self.app, "manual") def clean_map(self): """Remove all rectangles and polygons from the map """ self.zonesMap.removeAllMapRectangles() self.zonesMap.removeAllMapPolygons() def update_gui_from_preferences(self): """Update gui status of preferences frame from config file """ #print "\n- updating Preferences gui" onOff = {"on": True, "off": False} #1 Tab #check for update self.updateCBtn.setSelected(onOff[self.app.checkUpdate]) #tools status, enabled or not for toolIndex, tool in enumerate(self.app.realTools): if "tool.%s" % tool.name in self.app.properties.keys(): configstatus = self.app.properties.getProperty("tool.%s" % tool.name) else: configstatus = "on" # new tool self.toolsCBtns[toolIndex].setSelected(onOff[configstatus]) #layers preferences for mode, button in self.layersRBtns.iteritems(): button.setSelected(mode == self.app.layersMode) #max errors number self.maxErrorsNumberTextField.setText(str(self.app.maxErrorsNumber)) #stats panel self.app.dlg.update_favourite_zone_indicator() #2 Tab #favourite area self.update_favourite_area_gui_from_preferences() self.app.dlg.update_statsPanel_status() #3 Tab #tools preferences for tool in self.app.allTools: if hasattr(tool, 'prefs') and tool.prefsGui is not None: tool.prefsGui.update_gui(tool.prefs) def update_favourite_area_gui_from_preferences(self): #status self.favZoneStatusCBtn.setSelected(self.app.favouriteZoneStatus) #table #store zones to a temporary list, used to store changes #and save them when preferences dialog is closed self.app.tempZones = list(self.app.zones) self.zonesTable.getModel().setNumRows(0) for zone in self.app.tempZones: self.zonesTable.getModel().addRow( [zone.country, zone.icon, zone.name]) if self.app.favZone is not None: selectedRow = self.app.tempZones.index(self.app.favZone) self.zonesTable.setRowSelectionInterval(selectedRow, selectedRow) self.zonesTable.getColumnModel().getColumn(0).setMaxWidth(30) self.zonesTable.getColumnModel().getColumn(1).setMaxWidth(50) #enable or disable favourite zone buttons self.actionPerformed() ### fav area editing buttons ########################################### def on_removeBtn_clicked(self, e): rowsNum = self.zonesTable.getSelectedRows() rowsNum.reverse() for rowNum in rowsNum: del self.app.tempZones[rowNum] self.zonesTable.getModel().removeRow(rowNum) if len(self.app.tempZones) != 0: if rowNum == 0: self.zonesTable.setRowSelectionInterval(0, 0) else: self.zonesTable.setRowSelectionInterval(rowNum - 1, rowNum - 1) self.check_removeBtn_status() def check_removeBtn_status(self): if self.app.tempZones != [] and len( self.zonesTable.getSelectedRows()) != 0: self.removeBtn.setEnabled(True) else: self.removeBtn.setEnabled(False) self.clean_map() def on_newBtn_clicked(self, e): try: self.newZoneDialog except AttributeError: self.newZoneDialog = NewZoneDialog(self.app) bbox = self.app.get_frame_bounds() self.app.newZone = Zone(self.app, self.app.strings.getString("New_zone"), "rectangle", ",".join(["%0.4f" % x for x in bbox]), "") self.newZoneDialog.update_gui_from_preferences() self.newZoneDialog.show() ### Exit from preferences ############################################## def on_cancelBtn_clicked(self, event=None): if hasattr(self, "newZoneDialog") and self.newZoneDialog.isVisible(): self.newZoneDialog.close_dialog() self.dispose() def on_saveBtn_clicked(self, event): """Read preferences from gui and save them to config.properties file """ #print "\n- saving preferences to config file" onOff = {True: "on", False: "off"} #1 Tab #check for update self.app.properties.setProperty("check_for_update", onOff[self.updateCBtn.isSelected()]) #tools status for toolIndex, tool in enumerate(self.app.realTools): prop = "tool.%s" % tool.name toolCBtn = self.toolsCBtns[toolIndex] self.app.properties.setProperty(prop, onOff[toolCBtn.isSelected()]) #layers preferences for mode, button in self.layersRBtns.iteritems(): if button.isSelected(): self.app.properties.setProperty("layers_mode", mode) break #max errors number try: num = Integer.parseInt(self.maxErrorsNumberTextField.getText()) except NumberFormatException: num = "" self.app.properties.setProperty("max_errors_number", str(num)) #2 Tab #Favourite zones changes = { "new": [z for z in self.app.tempZones if not z in self.app.zones], "deleted": [z for z in self.app.zones if not z in self.app.tempZones] } #delete files of removed favourite zones for zone in changes["deleted"]: f = File( File.separator.join([ self.app.SCRIPTDIR, "configuration", "favourite_zones", "%s.txt" % zone.name ])) f.delete() #create files for new favourite zones for zone in changes["new"]: print "\nsave new zone", zone.name fileName = File.separator.join([ self.app.SCRIPTDIR, "configuration", "favourite_zones", "%s.txt" % zone.name ]) f = open(fileName, "w") zoneData = zone.geomString if zone.country != "": zoneData += "|" + zone.country f.write(zoneData.encode("utf-8")) f.close() self.app.zones = self.app.tempZones if len(self.app.zones) == 0: self.app.favZone = None self.app.properties.setProperty("favourite_area.name", "") self.favZoneStatusCBtn.setSelected(False) else: if len(self.zonesTable.getSelectedRows()) == 0: self.app.favZone = self.app.zones[0] else: self.app.favZone = self.app.zones[ self.zonesTable.getSelectedRows()[0]] self.app.properties.setProperty("favourite_area.name", self.app.favZone.name) favZoneStatus = self.favZoneStatusCBtn.isSelected() self.app.properties.setProperty("favourite_area.status", onOff[favZoneStatus]) self.app.favouriteZoneStatus = favZoneStatus #stats panel self.app.dlg.update_favourite_zone_indicator() self.app.dlg.update_statsPanel_status() #3 Tab #tools preferences for tool in self.app.allTools: if hasattr(tool, 'prefs') and tool.prefsGui is not None: for pref, value in tool.prefsGui.read_gui().iteritems(): prefKey = "tool.%s.%s" % (tool.name, pref) self.app.properties.setProperty(prefKey, value) self.app.save_config() self.dispose()
class PreferencesFrame(JFrame, ActionListener, WindowListener, ItemListener, HyperlinkListener): """Dialog with preferences """ def __init__(self, parent, title, app): from javax.swing import JCheckBox, JRadioButton, ButtonGroup self.app = app border = BorderFactory.createEmptyBorder(5, 7, 5, 7) self.getContentPane().setBorder(border) self.getContentPane().setLayout(BorderLayout(0, 5)) self.tabbedPane = JTabbedPane() #1 Tab: general panel1 = JPanel() panel1.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7)) panel1.setLayout(BoxLayout(panel1, BoxLayout.PAGE_AXIS)) #Checkbutton to enable/disable update check when script starts self.updateCBtn = JCheckBox(self.app.strings.getString("updateCBtn")) self.updateCBtn.setToolTipText(self.app.strings.getString("updateCBtn_tooltip")) #Download tools downloadBtn = JButton(self.app.strings.getString("updatesBtn"), ImageProvider.get("dialogs", "refresh"), actionPerformed=self.on_downloadBtn_clicked) downloadBtn.setToolTipText(self.app.strings.getString("updatesBtn_tooltip")) #Checkbuttons for enabling/disabling tools toolsPanel = JPanel(BorderLayout(0, 5)) title = self.app.strings.getString("enable_disable_tools") toolsPanel.setBorder(BorderFactory.createTitledBorder(title)) infoLbl = JLabel(self.app.strings.getString("JOSM_restart_warning")) infoLbl.setFont(infoLbl.getFont().deriveFont(Font.ITALIC)) toolsPanel.add(infoLbl, BorderLayout.PAGE_START) toolsStatusPane = JPanel(GridLayout(len(self.app.realTools), 0)) self.toolsCBtns = [] for tool in self.app.realTools: toolCBtn = JCheckBox() toolCBtn.addItemListener(self) toolLbl = JLabel(tool.title, tool.bigIcon, JLabel.LEFT) self.toolsCBtns.append(toolCBtn) toolPane = JPanel() toolPane.setLayout(BoxLayout(toolPane, BoxLayout.X_AXIS)) toolPane.add(toolCBtn) toolPane.add(toolLbl) toolsStatusPane.add(toolPane) toolsPanel.add(toolsStatusPane, BorderLayout.CENTER) #Radiobuttons for enabling/disabling layers when a new one #is added layersPanel = JPanel(GridLayout(0, 1)) title = self.app.strings.getString("errors_layers_manager") layersPanel.setBorder(BorderFactory.createTitledBorder(title)) errorLayersLbl = JLabel(self.app.strings.getString("errors_layers_info")) errorLayersLbl.setFont(errorLayersLbl.getFont().deriveFont(Font.ITALIC)) layersPanel.add(errorLayersLbl) self.layersRBtns = {} group = ButtonGroup() for mode in self.app.layersModes: layerRBtn = JRadioButton(self.app.strings.getString("%s" % mode)) group.add(layerRBtn) layersPanel.add(layerRBtn) self.layersRBtns[mode] = layerRBtn #Max number of errors text field self.maxErrorsNumberTextField = JTextField() self.maxErrorsNumberTextField.setToolTipText(self.app.strings.getString("maxErrorsNumberTextField_tooltip")) self.maxErrorsNumberTFieldDefaultBorder = self.maxErrorsNumberTextField.getBorder() self.maxErrorsNumberTextField.getDocument().addDocumentListener(ErrNumTextListener(self)) #layout self.updateCBtn.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(self.updateCBtn) panel1.add(Box.createRigidArea(Dimension(0, 15))) downloadBtn.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(downloadBtn) panel1.add(Box.createRigidArea(Dimension(0, 15))) toolsPanel.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(toolsPanel) panel1.add(Box.createRigidArea(Dimension(0, 15))) layersPanel.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(layersPanel) panel1.add(Box.createRigidArea(Dimension(0, 15))) maxErrP = JPanel(BorderLayout(5, 0)) maxErrP.add(JLabel(self.app.strings.getString("max_errors_number")), BorderLayout.LINE_START) maxErrP.add(self.maxErrorsNumberTextField, BorderLayout.CENTER) p = JPanel(BorderLayout()) p.add(maxErrP, BorderLayout.PAGE_START) p.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(p) self.tabbedPane.addTab(self.app.strings.getString("tab_1_title"), None, panel1, None) #2 Tab: favourite zones panel2 = JPanel(BorderLayout(5, 15)) panel2.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7)) #status topPanel = JPanel() topPanel.setLayout(BoxLayout(topPanel, BoxLayout.Y_AXIS)) infoPanel = HtmlPanel(self.app.strings.getString("fav_zones_info")) infoPanel.getEditorPane().addHyperlinkListener(self) infoPanel.setAlignmentX(Component.LEFT_ALIGNMENT) self.favZoneStatusCBtn = JCheckBox(self.app.strings.getString("activate_fav_area"), actionListener=self) self.favZoneStatusCBtn.setToolTipText(self.app.strings.getString("activate_fav_area_tooltip")) self.favZoneStatusCBtn.setAlignmentX(Component.LEFT_ALIGNMENT) topPanel.add(infoPanel) topPanel.add(Box.createRigidArea(Dimension(0, 10))) topPanel.add(self.favZoneStatusCBtn) #table self.zonesTable = JTable() tableSelectionModel = self.zonesTable.getSelectionModel() tableSelectionModel.addListSelectionListener(ZonesTableListener(self)) columns = ["", self.app.strings.getString("Type"), self.app.strings.getString("Name")] tableModel = ZonesTableModel([], columns) self.zonesTable.setModel(tableModel) self.scrollPane = JScrollPane(self.zonesTable) #map self.zonesMap = JMapViewer() self.zonesMap.setZoomContolsVisible(False) self.zonesMap.setMinimumSize(Dimension(100, 200)) #buttons self.removeBtn = JButton(self.app.strings.getString("Remove"), ImageProvider.get("dialogs", "delete"), actionPerformed=self.on_removeBtn_clicked) self.removeBtn.setToolTipText(self.app.strings.getString("remove_tooltip")) newBtn = JButton(self.app.strings.getString("New"), ImageProvider.get("dialogs", "add"), actionPerformed=self.on_newBtn_clicked) newBtn.setToolTipText(self.app.strings.getString("new_tooltip")) #layout panel2.add(topPanel, BorderLayout.PAGE_START) panel2.add(self.scrollPane, BorderLayout.LINE_START) panel2.add(self.zonesMap, BorderLayout.CENTER) self.buttonsPanel = JPanel() self.buttonsPanel.add(self.removeBtn) self.buttonsPanel.add(newBtn) panel2.add(self.buttonsPanel, BorderLayout.PAGE_END) self.tabbedPane.addTab(self.app.strings.getString("tab_2_title"), None, panel2, None) #3 Tab Tools options panel3 = JPanel() panel3.setLayout(BoxLayout(panel3, BoxLayout.Y_AXIS)) panel3.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7)) for tool in self.app.realTools: if hasattr(tool, 'prefs'): p = JPanel(FlowLayout(FlowLayout.LEFT)) p.setBorder(BorderFactory.createTitledBorder(tool.title)) p.add(tool.prefsGui) panel3.add(p) self.tabbedPane.addTab(self.app.strings.getString("tab_3_title"), None, panel3, None) self.add(self.tabbedPane, BorderLayout.CENTER) exitPanel = JPanel() saveBtn = JButton(self.app.strings.getString("OK"), ImageProvider.get("ok"), actionPerformed=self.on_saveBtn_clicked) cancelBtn = JButton(self.app.strings.getString("cancel"), ImageProvider.get("cancel"), actionPerformed=self.on_cancelBtn_clicked) saveBtn.setToolTipText(self.app.strings.getString("save_preferences")) saveBtn.setAlignmentX(0.5) exitPanel.add(saveBtn) exitPanel.add(cancelBtn) self.add(exitPanel, BorderLayout.PAGE_END) self.addWindowListener(self) self.pack() def windowClosing(self, windowEvent): self.on_cancelBtn_clicked() def hyperlinkUpdate(self, e): if e.getEventType() == HyperlinkEvent.EventType.ACTIVATED: OpenBrowser.displayUrl(e.getURL().toString()) def itemStateChanged(self, e): """A ttol has been activated/deactivated. Check if at least one tool is on. """ if all(not button.isSelected() for button in self.toolsCBtns): JOptionPane.showMessageDialog( Main.parent, self.app.strings.getString("tools_disabled_warning"), self.app.strings.getString("tools_disabled_warning_title"), JOptionPane.WARNING_MESSAGE) source = e.getItemSelectable() source.setSelected(True) def actionPerformed(self, e=None): """Enable/disable favourite zones panel """ for container in (self.scrollPane, self.buttonsPanel): self.enableComponents(container, self.favZoneStatusCBtn.isSelected()) if self.favZoneStatusCBtn.isSelected(): self.check_removeBtn_status() def enableComponents(self, container, enable): components = container.getComponents() for component in components: component.setEnabled(enable) if isinstance(component, Container): self.enableComponents(component, enable) def on_downloadBtn_clicked(self, e): update_checker.Updater(self.app, "manual") def clean_map(self): """Remove all rectangles and polygons from the map """ self.zonesMap.removeAllMapRectangles() self.zonesMap.removeAllMapPolygons() def update_gui_from_preferences(self): """Update gui status of preferences frame from config file """ #print "\n- updating Preferences gui" onOff = {"on": True, "off": False} #1 Tab #check for update self.updateCBtn.setSelected(onOff[self.app.checkUpdate]) #tools status, enabled or not for toolIndex, tool in enumerate(self.app.realTools): if "tool.%s" % tool.name in self.app.properties.keys(): configstatus = self.app.properties.getProperty("tool.%s" % tool.name) else: configstatus = "on" # new tool self.toolsCBtns[toolIndex].setSelected(onOff[configstatus]) #layers preferences for mode, button in self.layersRBtns.iteritems(): button.setSelected(mode == self.app.layersMode) #max errors number self.maxErrorsNumberTextField.setText(str(self.app.maxErrorsNumber)) #stats panel self.app.dlg.update_favourite_zone_indicator() #2 Tab #favourite area self.update_favourite_area_gui_from_preferences() self.app.dlg.update_statsPanel_status() #3 Tab #tools preferences for tool in self.app.allTools: if hasattr(tool, 'prefs') and tool.prefsGui is not None: tool.prefsGui.update_gui(tool.prefs) def update_favourite_area_gui_from_preferences(self): #status self.favZoneStatusCBtn.setSelected(self.app.favouriteZoneStatus) #table #store zones to a temporary list, used to store changes #and save them when preferences dialog is closed self.app.tempZones = list(self.app.zones) self.zonesTable.getModel().setNumRows(0) for zone in self.app.tempZones: self.zonesTable.getModel().addRow([zone.country, zone.icon, zone.name]) if self.app.favZone is not None: selectedRow = self.app.tempZones.index(self.app.favZone) self.zonesTable.setRowSelectionInterval(selectedRow, selectedRow) self.zonesTable.getColumnModel().getColumn(0).setMaxWidth(30) self.zonesTable.getColumnModel().getColumn(1).setMaxWidth(50) #enable or disable favourite zone buttons self.actionPerformed() ### fav area editing buttons ########################################### def on_removeBtn_clicked(self, e): rowsNum = self.zonesTable.getSelectedRows() rowsNum.reverse() for rowNum in rowsNum: del self.app.tempZones[rowNum] self.zonesTable.getModel().removeRow(rowNum) if len(self.app.tempZones) != 0: if rowNum == 0: self.zonesTable.setRowSelectionInterval(0, 0) else: self.zonesTable.setRowSelectionInterval(rowNum - 1, rowNum - 1) self.check_removeBtn_status() def check_removeBtn_status(self): if self.app.tempZones != [] and len(self.zonesTable.getSelectedRows()) != 0: self.removeBtn.setEnabled(True) else: self.removeBtn.setEnabled(False) self.clean_map() def on_newBtn_clicked(self, e): try: self.newZoneDialog except AttributeError: self.newZoneDialog = NewZoneDialog(self.app) bbox = self.app.get_frame_bounds() self.app.newZone = Zone(self.app, self.app.strings.getString("New_zone"), "rectangle", ",".join(["%0.4f" % x for x in bbox]), "") self.newZoneDialog.update_gui_from_preferences() self.newZoneDialog.show() ### Exit from preferences ############################################## def on_cancelBtn_clicked(self, event=None): if hasattr(self, "newZoneDialog") and self.newZoneDialog.isVisible(): self.newZoneDialog.close_dialog() self.dispose() def on_saveBtn_clicked(self, event): """Read preferences from gui and save them to config.properties file """ #print "\n- saving preferences to config file" onOff = {True: "on", False: "off"} #1 Tab #check for update self.app.properties.setProperty("check_for_update", onOff[self.updateCBtn.isSelected()]) #tools status for toolIndex, tool in enumerate(self.app.realTools): prop = "tool.%s" % tool.name toolCBtn = self.toolsCBtns[toolIndex] self.app.properties.setProperty(prop, onOff[toolCBtn.isSelected()]) #layers preferences for mode, button in self.layersRBtns.iteritems(): if button.isSelected(): self.app.properties.setProperty("layers_mode", mode) break #max errors number try: num = Integer.parseInt(self.maxErrorsNumberTextField.getText()) except NumberFormatException: num = "" self.app.properties.setProperty("max_errors_number", str(num)) #2 Tab #Favourite zones changes = {"new": [z for z in self.app.tempZones if not z in self.app.zones], "deleted": [z for z in self.app.zones if not z in self.app.tempZones]} #delete files of removed favourite zones for zone in changes["deleted"]: f = File(File.separator.join([self.app.SCRIPTDIR, "configuration", "favourite_zones", "%s.txt" % zone.name])) f.delete() #create files for new favourite zones for zone in changes["new"]: print "\nsave new zone", zone.name fileName = File.separator.join([self.app.SCRIPTDIR, "configuration", "favourite_zones", "%s.txt" % zone.name]) f = open(fileName, "w") zoneData = zone.geomString if zone.country != "": zoneData += "|" + zone.country f.write(zoneData.encode("utf-8")) f.close() self.app.zones = self.app.tempZones if len(self.app.zones) == 0: self.app.favZone = None self.app.properties.setProperty("favourite_area.name", "") self.favZoneStatusCBtn.setSelected(False) else: if len(self.zonesTable.getSelectedRows()) == 0: self.app.favZone = self.app.zones[0] else: self.app.favZone = self.app.zones[self.zonesTable.getSelectedRows()[0]] self.app.properties.setProperty("favourite_area.name", self.app.favZone.name) favZoneStatus = self.favZoneStatusCBtn.isSelected() self.app.properties.setProperty("favourite_area.status", onOff[favZoneStatus]) self.app.favouriteZoneStatus = favZoneStatus #stats panel self.app.dlg.update_favourite_zone_indicator() self.app.dlg.update_statsPanel_status() #3 Tab #tools preferences for tool in self.app.allTools: if hasattr(tool, 'prefs') and tool.prefsGui is not None: for pref, value in tool.prefsGui.read_gui().iteritems(): prefKey = "tool.%s.%s" % (tool.name, pref) self.app.properties.setProperty(prefKey, value) self.app.save_config() self.dispose()
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, ActionListener, DocumentListener): # # implement IBurpExtender # def registerExtenderCallbacks(self, callbacks): # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("Response Clusterer") # create the log and a lock on which to synchronize when adding log entries self._log = ArrayList() self._lock = Lock() # main split pane self._main_jtabedpane = JTabbedPane() # The split pane with the log and request/respponse details self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT) # table of log entries logTable = Table(self) scrollPane = JScrollPane(logTable) self._splitpane.setLeftComponent(scrollPane) # List of log entries self._log_entries = [] # tabs with request/response viewers tabs = JTabbedPane() self._requestViewer = callbacks.createMessageEditor(self, False) self._responseViewer = callbacks.createMessageEditor(self, False) tabs.addTab("Request", self._requestViewer.getComponent()) tabs.addTab("Response", self._responseViewer.getComponent()) self._splitpane.setRightComponent(tabs) #Setup the options self._optionsJPanel = JPanel() gridBagLayout = GridBagLayout() gbc = GridBagConstraints() self._optionsJPanel.setLayout(gridBagLayout) self.max_clusters = 500 self.JLabel_max_clusters = JLabel("Maximum amount of clusters: ") gbc.gridy = 0 gbc.gridx = 0 self._optionsJPanel.add(self.JLabel_max_clusters, gbc) self.JTextField_max_clusters = JTextField(str(self.max_clusters), 5) self.JTextField_max_clusters.getDocument().addDocumentListener(self) gbc.gridx = 1 self._optionsJPanel.add(self.JTextField_max_clusters, gbc) callbacks.customizeUiComponent(self.JLabel_max_clusters) callbacks.customizeUiComponent(self.JTextField_max_clusters) self.similarity = 0.95 self.JLabel_similarity = JLabel("Similarity (between 0 and 1)") gbc.gridy = 1 gbc.gridx = 0 self._optionsJPanel.add(self.JLabel_similarity, gbc) self.JTextField_similarity = JTextField(str(self.similarity), 5) self.JTextField_similarity.getDocument().addDocumentListener(self) gbc.gridx = 1 self._optionsJPanel.add(self.JTextField_similarity, gbc) callbacks.customizeUiComponent(self.JLabel_similarity) callbacks.customizeUiComponent(self.JTextField_similarity) self.use_quick_similar = False self.JLabel_use_quick_similar = JLabel( "Use set intersection of space splitted tokens for similarity (default: optimized difflib.SequenceMatcher.quick_ratio)" ) gbc.gridy = 2 gbc.gridx = 0 self._optionsJPanel.add(self.JLabel_use_quick_similar, gbc) self.JCheckBox_use_quick_similar = JCheckBox("") self.JCheckBox_use_quick_similar.addActionListener(self) gbc.gridx = 1 self._optionsJPanel.add(self.JCheckBox_use_quick_similar, gbc) callbacks.customizeUiComponent(self.JCheckBox_use_quick_similar) self.response_max_size = 10 * 1024 #10kb self.JLabel_response_max_size = JLabel("Response max size (bytes)") gbc.gridy = 3 gbc.gridx = 0 self._optionsJPanel.add(self.JLabel_response_max_size, gbc) self.JTextField_response_max_size = JTextField( str(self.response_max_size), 5) self.JTextField_response_max_size.getDocument().addDocumentListener( self) gbc.gridx = 1 self._optionsJPanel.add(self.JTextField_response_max_size, gbc) callbacks.customizeUiComponent(self.JLabel_response_max_size) callbacks.customizeUiComponent(self.JTextField_response_max_size) self.uninteresting_mime_types = ('JPEG', 'CSS', 'GIF', 'script', 'GIF', 'PNG', 'image') self.uninteresting_status_codes = () self.uninteresting_url_file_extensions = ('js', 'css', 'zip', 'war', 'jar', 'doc', 'docx', 'xls', 'xlsx', 'pdf', 'exe', 'dll', 'png', 'jpeg', 'jpg', 'bmp', 'tif', 'tiff', 'gif', 'webp', 'm3u', 'mp4', 'm4a', 'ogg', 'aac', 'flac', 'mp3', 'wav', 'avi', 'mov', 'mpeg', 'wmv', 'swf', 'woff', 'woff2') about = "<html>" about += "Author: floyd, @floyd_ch, http://www.floyd.ch<br>" about += "modzero AG, http://www.modzero.ch<br>" about += "<br>" about += "<h3>Getting an overview of the tested website</h3>" about += "<p style=\"width:500px\">" about += "This plugin clusters all response bodies by similarity and shows a summary, one request/response per cluster. " about += 'Adjust similarity in the options if you get too few or too many entries in the "One member of each cluster" ' about += "tab. The plugin will allow a tester to get an overview of the tested website's responses from all tools (scanner, proxy, etc.). " about += "As similarity comparison " about += "can use a lot of ressources, only small, in-scope responses that have interesting response codes, " about += "file extensions and mime types are processed. " about += "</p>" about += "</html>" self.JLabel_about = JLabel(about) self.JLabel_about.setLayout(GridBagLayout()) self._aboutJPanel = JScrollPane(self.JLabel_about) # customize our UI components callbacks.customizeUiComponent(self._splitpane) callbacks.customizeUiComponent(logTable) callbacks.customizeUiComponent(scrollPane) callbacks.customizeUiComponent(tabs) # add the splitpane and options to the main jtabedpane self._main_jtabedpane.addTab("One member of each cluster", None, self._splitpane, None) self._main_jtabedpane.addTab("Options", None, self._optionsJPanel, None) self._main_jtabedpane.addTab("About & README", None, self._aboutJPanel, None) # clusters will grow up to self.max_clusters response bodies... self._clusters = set() self.Similarity = Similarity() # Now load the already stored with self._lock: log_entries_from_storage = self.load_project_setting("log_entries") if log_entries_from_storage: for toolFlag, req, resp, url in log_entries_from_storage: try: self.add_new_log_entry(toolFlag, req, resp, url) except Exception as e: print "Exception when deserializing a stored log entry", toolFlag, url print e # Important: Do this at the very end (otherwise we could run into troubles locking up entire threads) # add the custom tab to Burp's UI callbacks.addSuiteTab(self) # register ourselves as an HTTP listener callbacks.registerHttpListener(self) # # implement what happens when options are changed # def changedUpdate(self, document): pass def removeUpdate(self, document): self.actionPerformed(None) def insertUpdate(self, document): self.actionPerformed(None) def actionPerformed(self, actionEvent): self.use_quick_similar = self.JCheckBox_use_quick_similar.isSelected() try: self.max_clusters = int(self.JTextField_max_clusters.getText()) except: self.JTextField_max_clusters.setText("200") try: self.similarity = float(self.JTextField_similarity.getText()) if self.similarity > 1.0 or self.similarity < 0.0: self.JTextField_similarity.setText("0.9") except: self.JTextField_similarity.setText("0.9") try: self.response_max_size = float( self.JTextField_response_max_size.getText()) if self.response_max_size < 0.0: self.JTextField_response_max_size.setText(str(10 * 1024)) except: self.JTextField_response_max_size.setText(str(10 * 1024)) print self.JCheckBox_use_quick_similar.isSelected( ), self.JTextField_max_clusters.getText( ), self.JTextField_similarity.getText( ), self.JTextField_response_max_size.getText() # # implement ITab # def getTabCaption(self): return "Response Clusterer" def getUiComponent(self): return self._main_jtabedpane # # implement IHttpListener # def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): if not messageIsRequest: if len(self._clusters) >= self.max_clusters: return resp = messageInfo.getResponse() if len(resp) >= self.response_max_size: print "Message was too long" return iResponseInfo = self._helpers.analyzeResponse(resp) mime_type = iResponseInfo.getStatedMimeType() if mime_type in self.uninteresting_mime_types: print "Mime type", mime_type, "is ignored" return if iResponseInfo.getStatusCode( ) in self.uninteresting_status_codes: print "Status code", iResponseInfo.getStatusCode( ), "is ignored" return req = messageInfo.getRequest() iRequestInfo = self._helpers.analyzeRequest(messageInfo) if not iRequestInfo.getUrl(): print "iRequestInfo.getUrl() returned None, so bailing out of analyzing this request" return if '.' in iRequestInfo.getUrl().getFile() and iRequestInfo.getUrl( ).getFile().split( '.')[-1] in self.uninteresting_url_file_extensions: print iRequestInfo.getUrl().getFile().split( '.')[-1], "is an ignored file extension" return if not self._callbacks.isInScope(iRequestInfo.getUrl()): print iRequestInfo.getUrl(), "is not in scope" return body = resp[iResponseInfo.getBodyOffset():] with self._lock: similarity_func = self.Similarity.similar if self.use_quick_similar: similarity_func = self.Similarity.quick_similar start_time = time.time() for response_code, item in self._clusters: if not response_code == iResponseInfo.getStatusCode(): #Different response codes -> different clusters continue if similarity_func(str(body), str(item), self.similarity): return #break else: #when no break/return occures in the for loop self.add_new_log_entry(toolFlag, req, resp, iRequestInfo.getUrl().toString()) self.save_project_setting("log_entries", self._log_entries) taken_time = time.time() - start_time if taken_time > 0.5: print "Plugin took", taken_time, "seconds to process request... body length:", len( body), "current cluster length:", len(self._clusters) print "URL:", str(iRequestInfo.getUrl()), def add_new_log_entry(self, toolFlag, request, response, service_url): self._log_entries.append((toolFlag, request, response, service_url)) iResponseInfo = self._helpers.analyzeResponse(response) body = response[iResponseInfo.getBodyOffset():] self._clusters.add((iResponseInfo.getStatusCode(), str(body))) row = self._log.size() service = CustomHttpService(service_url) r = CustomRequestResponse(None, None, service, request, response) iRequestInfo = self._helpers.analyzeRequest(r) self._log.add( LogEntry(toolFlag, self._callbacks.saveBuffersToTempFiles(r), iRequestInfo.getUrl())) self.fireTableRowsInserted(row, row) # # extend AbstractTableModel # def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 2 def getColumnName(self, columnIndex): if columnIndex == 0: return "Tool" if columnIndex == 1: return "URL" return "" def getValueAt(self, rowIndex, columnIndex): logEntry = self._log.get(rowIndex) if columnIndex == 0: return self._callbacks.getToolName(logEntry._tool) if columnIndex == 1: return logEntry._url.toString() return "" # # implement IMessageEditorController # this allows our request/response viewers to obtain details about the messages being displayed # def getHttpService(self): return self._currentlyDisplayedItem.getHttpService() def getRequest(self): return self._currentlyDisplayedItem.getRequest() def getResponse(self): return self._currentlyDisplayedItem.getResponse() def save_project_setting(self, name, value): value = pickle.dumps(value).encode("base64") request = "GET /"+name+" HTTP/1.0\r\n\r\n" \ "You can ignore this item in the site map. It was created by the ResponseClusterer extension. The \n" \ "reason is that the Burp API is missing a certain functionality to save settings. \n" \ "TODO Burp API limitation: This is a hackish way to be able to store project-scope settings.\n" \ "We don't want to restore requests/responses of tabs in a totally different Burp project.\n" \ "However, unfortunately there is no saveExtensionProjectSetting in the Burp API :(\n" \ "So we have to abuse the addToSiteMap API to store project-specific things\n" \ "Even when using this hack we currently cannot persist Collaborator interaction checks\n" \ "(IBurpCollaboratorClientContext is not serializable and Threads loose their Python class\n" \ "functionality when unloaded) due to Burp API limitations." response = None if value: response = "HTTP/1.1 200 OK\r\n" + value rr = CustomRequestResponse( name, '', CustomHttpService('http://responseclustererextension.local/'), request, response) self._callbacks.addToSiteMap(rr) def load_project_setting(self, name): rrs = self._callbacks.getSiteMap( 'http://responseclustererextension.local/' + name) if rrs: rr = rrs[0] if rr.getResponse(): val = "\r\n".join( FloydsHelpers.jb2ps(rr.getResponse()).split("\r\n")[1:]) return pickle.loads(val.decode("base64")) else: return None else: return None
class BurpExtender(IBurpExtender, IScannerCheck, ITab): def __init__(self): self.ext_name = 'AWS Extender' self.callbacks = None self.gui_elements = None self.aws_access_key_inpt = None self.aws_secret_key_inpt = None self.aws_session_token_inpt = None self.gs_access_key_inpt = None self.gs_secret_key_inpt = None self.wordlist_path_inpt = None self.checkbox_inpt = None self.aws_access_key = '' self.aws_secret_key = '' self.aws_session_token = '' self.gs_access_key = '' self.gs_secret_key = '' self.wordlist_path = '' def registerExtenderCallbacks(self, callbacks): """Register extender callbacks.""" self.callbacks = callbacks # Set the name of the extension self.callbacks.setExtensionName(self.ext_name) # Register the extension as a scanner check self.callbacks.registerScannerCheck(self) # Build GUI elements self.gui_elements = self.build_gui() callbacks.customizeUiComponent(self.gui_elements) callbacks.addSuiteTab(self) self.check_loading_issues() self.reload_config() def show_errors(self, label): """Display error messages.""" top_label = JLabel(label, JLabel.CENTER) frame = JFrame(self.ext_name) frame.setSize(550, 300) frame.setLayout(GridLayout(1, 1)) frame.add(top_label) frame.setLocationRelativeTo(None) frame.setVisible(True) def check_loading_issues(self): """Check for any loading issues.""" missing_libs = [] tips = [] label = """<html> <body style='margin: 10px'> <b>The following dependencies could not be loaded successfully:</b><br> <ul><li>%s</li></ul><br> <b>Tips:</b><br> <ul><li>%s</li><br></ul> <b>For detailed information on how to load the plugin, see:</b><br> <ul> <li> <a href='#'>https://github.com/VirtueSecurity/aws-extender#getting-started</a> </li> </ul> </body> </html>""" if not RUN_TESTS: missing_libs.append('boto/boto3') tips.append( 'Make sure that the boto/boto3 library is installed properly, and\ the right path is specified in the "Folder for loading modules" setting.' ) try: CET.fromstring('<test></test>') except SAXException: # Try to workaround "http://bugs.jython.org/issue1127" try: def xml_parser(**_): class Parser(object): def feed(*_): raise XMLParseError def close(*_): return None return Parser() CET.XMLParser = xml_parser except TypeError: missing_libs.append('SAXParser') tips.append("""Run Burp Suite using the following command: <br><code style='background: #f7f7f9; color: red'>$ java -classpath xercesImpl.jar;burpsuite_pro.jar burp.StartBurp</code>""") if not missing_libs: return label %= ('</li><li>'.join(missing_libs), '</li><li>'.join(tips)) self.show_errors(label) def build_gui(self): """Construct GUI elements.""" panel = JPanel(BorderLayout(3, 3)) panel.setBorder(EmptyBorder(160, 160, 160, 160)) self.aws_access_key_inpt = JTextField(10) self.aws_secret_key_inpt = JTextField(10) self.aws_session_token_inpt = JTextField(10) self.gs_access_key_inpt = JTextField(10) self.gs_secret_key_inpt = JTextField(10) self.wordlist_path_inpt = JTextField(10) self.checkbox_inpt = JCheckBox('Enabled') save_btn = JButton('Save', actionPerformed=self.save_config) labels = JPanel(GridLayout(0, 1)) inputs = JPanel(GridLayout(0, 1)) panel.add(labels, BorderLayout.WEST) panel.add(inputs, BorderLayout.CENTER) top_label = JLabel('<html><b>Settings</b><br><br></html>') top_label.setHorizontalAlignment(JLabel.CENTER) panel.add(top_label, BorderLayout.NORTH) labels.add(JLabel('AWS Access Key:')) inputs.add(self.aws_access_key_inpt) labels.add(JLabel('AWS Secret Key:')) inputs.add(self.aws_secret_key_inpt) labels.add(JLabel('AWS Session Key (optional):')) inputs.add(self.aws_session_token_inpt) labels.add(JLabel('GS Access Key:')) inputs.add(self.gs_access_key_inpt) labels.add(JLabel('GS Secret Key:')) inputs.add(self.gs_secret_key_inpt) labels.add(JLabel('Wordlist Filepath (optional):')) inputs.add(self.wordlist_path_inpt) labels.add(JLabel('Passive Mode:')) inputs.add(self.checkbox_inpt) panel.add(save_btn, BorderLayout.SOUTH) return panel def save_config(self, _): """Save settings.""" error_message = '' wordlist_path = self.wordlist_path_inpt.getText() save_setting = self.callbacks.saveExtensionSetting save_setting('aws_access_key', self.aws_access_key_inpt.getText()) save_setting('aws_secret_key', self.aws_secret_key_inpt.getText()) save_setting('aws_session_token', self.aws_session_token_inpt.getText()) save_setting('gs_access_key', self.gs_access_key_inpt.getText()) save_setting('gs_secret_key', self.gs_secret_key_inpt.getText()) save_setting('wordlist_path', wordlist_path) if self.checkbox_inpt.isSelected(): save_setting('passive_mode', 'True') else: save_setting('passive_mode', '') if wordlist_path and not os.path.isfile(wordlist_path): error_message = 'Error: Invalid filepath for the "Wordlist Filepath" setting.' self.show_errors(error_message) self.reload_config() def reload_config(self): """Reload saved settings.""" global RUN_TESTS load_setting = self.callbacks.loadExtensionSetting aws_access_key_val = load_setting('aws_access_key') or '' aws_secret_key_val = load_setting('aws_secret_key') or '' aws_session_token_val = load_setting('aws_session_token') or '' gs_access_key_val = load_setting('gs_access_key') or '' gs_secret_key_val = load_setting('gs_secret_key') or '' wordlist_path_val = load_setting('wordlist_path') or '' checkbox_inpt_val = load_setting('passive_mode') checkbox_inpt_val = bool( str(checkbox_inpt_val)) if checkbox_inpt_val else False if checkbox_inpt_val: RUN_TESTS = False else: RUN_TESTS = True self.aws_access_key = aws_access_key_val self.aws_secret_key = aws_secret_key_val self.aws_session_token = aws_session_token_val self.gs_access_key = gs_access_key_val self.gs_secret_key = gs_secret_key_val self.wordlist_path = wordlist_path_val self.aws_access_key_inpt.setText(aws_access_key_val) self.aws_secret_key_inpt.setText(aws_secret_key_val) self.aws_session_token_inpt.setText(aws_session_token_val) self.gs_access_key_inpt.setText(gs_access_key_val) self.gs_secret_key_inpt.setText(gs_secret_key_val) self.wordlist_path_inpt.setText(wordlist_path_val) self.checkbox_inpt.setSelected(checkbox_inpt_val) def getTabCaption(self): """Return tab caption.""" return self.ext_name def getUiComponent(self): """Return GUI elements.""" return self.gui_elements def doPassiveScan(self, request_response): """Perform a passive scan.""" scan_issues = [] opts = { 'aws_access_key': self.aws_access_key, 'aws_secret_key': self.aws_secret_key, 'aws_session_token': self.aws_session_token, 'gs_access_key': self.gs_access_key, 'gs_secret_key': self.gs_secret_key, 'wordlist_path': self.wordlist_path } bucket_scan = BucketScan(request_response, self.callbacks, opts) bucket_issues = bucket_scan.check_buckets() cognito_scan = CognitoScan(request_response, self.callbacks) cognito_issues = cognito_scan.identify_identity_pools() scan_issues = bucket_issues + cognito_issues if len(scan_issues) > 0: return scan_issues return None @staticmethod def doActiveScan(*_): pass @staticmethod def consolidateDuplicateIssues(existing_issue, new_issue): """Eliminate duplicate issues.""" if existing_issue.getIssueDetail() == new_issue.getIssueDetail(): return -1 else: return 0
class BurpExtender(IBurpExtender, ISessionHandlingAction, IExtensionStateListener, IHttpListener, ITab): def registerExtenderCallbacks(self, callbacks): self.callbacks = callbacks self.helpers = callbacks.helpers self.checkboxEnable = JCheckBox('Enabled') self.checkboxEnable.setSelected(False) self.checkboxEnable.setEnabled(True) self.scriptpane = JTextPane() self.scriptpane.setFont(Font('Monospaced', Font.PLAIN, 11)) self.scrollpane = JScrollPane() self.scrollpane.setViewportView(self.scriptpane) self.tab = JPanel() layout = GroupLayout(self.tab) self.tab.setLayout(layout) layout.setAutoCreateGaps(True) layout.setAutoCreateContainerGaps(True) layout.setHorizontalGroup(layout.createParallelGroup().addComponent( self.checkboxEnable).addComponent(self.scrollpane)) layout.setVerticalGroup(layout.createSequentialGroup().addComponent( self.checkboxEnable).addComponent(self.scrollpane)) self._code = compile('', '<string>', 'exec') self._script = '' script = callbacks.loadExtensionSetting('script') if script: script = base64.b64decode(script) self.scriptpane.document.insertString( self.scriptpane.document.length, script, SimpleAttributeSet()) self._script = script try: self._code = compile(script, '<string>', 'exec') except Exception as e: traceback.print_exc(file=self.callbacks.getStderr()) callbacks.setExtensionName("Python Scripter (modified)") callbacks.registerSessionHandlingAction(self) callbacks.registerExtensionStateListener(self) callbacks.registerHttpListener(self) callbacks.customizeUiComponent(self.getUiComponent()) callbacks.addSuiteTab(self) self.scriptpane.requestFocus() return def getActionName(self): return 'Send to Python Scripter' def extensionUnloaded(self): try: self.callbacks.saveExtensionSetting('script', base64.b64encode(self._script)) except Exception: traceback.print_exc(file=self.callbacks.getStderr()) return def performAction(self, currentRequest, macroItems): self.processHttpMessage(self.callbacks.TOOL_MACRO, 1, currentRequest, macroItems) return def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo, macroItems=[]): if not self.checkboxEnable.isSelected(): return try: globals_ = {} locals_ = { 'extender': self, 'callbacks': self.callbacks, 'helpers': self.helpers, 'toolFlag': toolFlag, 'messageIsRequest': messageIsRequest, 'messageInfo': messageInfo, 'macroItems': macroItems } exec(self.script, globals_, locals_) except Exception: traceback.print_exc(file=self.callbacks.getStderr()) return def getTabCaption(self): return 'Script' def getUiComponent(self): return self.tab @property def script(self): end = self.scriptpane.document.length _script = self.scriptpane.document.getText(0, end) if _script == self._script: return self._code self._script = _script self._code = compile(_script, '<string>', 'exec') return self._code
class BurpExtender(IBurpExtender, IHttpListener, IMessageEditorTabFactory, ITab): # # implement IBurpExtender # def registerExtenderCallbacks(self, callbacks): global EXTENSION_NAME sys.stdout = callbacks.getStdout() sys.stderr = callbacks.getStderr() # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName(EXTENSION_NAME) # register ourselves as a Http Listener callbacks.registerHttpListener(self) # register ourselves as a message editor tab factory callbacks.registerMessageEditorTabFactory(self) # setup the UI self.initGui() # add the custom tab to Burp's UI self._callbacks.addSuiteTab(self) return # # create the Gui # def initGui(self): #~ if DEBUG: #~ import pdb; #~ pdb.set_trace() tabPane = JTabbedPane(JTabbedPane.TOP) CreditsText = "<html># Burp Custom Deserializer<br/># Copyright (c) 2016, Marco Tinari<br/>#<br/># This program is free software: you can redistribute it and/or modify<br/># it under the terms of the GNU General Public License as published by<br/># the Free Software Foundation, either version 3 of the License, or<br/># (at your option) any later version.<br/>#<br/># This program is distributed in the hope that it will be useful,<br/># but WITHOUT ANY WARRANTY; without even the implied warranty of<br/># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br/># GNU General Public License for more details.<br/>#<br/># You should have received a copy of the GNU General Public License<br/># along with this program. If not, see <http://www.gnu.org/licenses/>.)<br/></html>" label1 = JLabel("<html>Usage:<br>1 - Select the desired encoding functions<br>2 - Enter the name of the parameter in the input field below and press the Apply button!</html>") label2 = JLabel(CreditsText) panel1 = JPanel() #set layout panel1.setLayout(GridLayout(11,1)) panel2 = JPanel() panel1.add(label1) panel2.add(label2) tabPane.addTab("Configuration", panel1) tabPane.addTab("Credits", panel2) applyButton = JButton('Apply',actionPerformed=self.reloadConf) panel1.add(applyButton, BorderLayout.SOUTH) #define GET/POST/COOKIE radio button self.GETparameterTypeRadioButton = JRadioButton('GET parameter') self.POSTparameterTypeRadioButton = JRadioButton('POST parameter') self.COOKIEparameterTypeRadioButton = JRadioButton('COOKIE parameter') self.POSTparameterTypeRadioButton.setSelected(True) group = ButtonGroup() group.add(self.GETparameterTypeRadioButton) group.add(self.POSTparameterTypeRadioButton) group.add(self.COOKIEparameterTypeRadioButton) self.base64Enabled = JCheckBox("Base64 encode") self.URLEnabled = JCheckBox("URL encode") self.ASCII2HexEnabled = JCheckBox("ASCII to Hex") self.ScannerEnabled = JCheckBox("<html>Enable serialization in Burp Scanner<br>Usage:<br>1.Place unencoded values inside intruder request and define the placeholder positions<br>2.rightclick->Actively scan defined insertion points)</html>") self.IntruderEnabled = JCheckBox("<html>Enable serialization in Burp Intruder<br>Usage:<br>1.Place unencoded values inside intruder request and define the placeholder positions<br>2.Start the attack</html>") self.parameterName = JTextField("Parameter name goes here...",60) #set the tooltips self.parameterName.setToolTipText("Fill in the parameter name and apply") self.base64Enabled.setToolTipText("Enable base64 encoding/decoding") self.ASCII2HexEnabled.setToolTipText("Enable ASCII 2 Hex encoding/decoding") self.URLEnabled.setToolTipText("Enable URL encoding/decoding") self.IntruderEnabled.setToolTipText("Check this if You want the extension to intercept and modify every request made by the Burp Intruder containing the selected paramter") self.ScannerEnabled.setToolTipText("Check this if You want the extension to intercept and modify every request made by the Burp Scanner containing the selected paramter") #add checkboxes to the panel panel1.add(self.parameterName) panel1.add(self.POSTparameterTypeRadioButton) panel1.add(self.GETparameterTypeRadioButton) panel1.add(self.COOKIEparameterTypeRadioButton) panel1.add(self.base64Enabled) panel1.add(self.URLEnabled) panel1.add(self.ASCII2HexEnabled) panel1.add(self.IntruderEnabled) panel1.add(self.ScannerEnabled) #assign tabPane self.tab = tabPane def reloadConf(self,event): #~ if DEBUG: #~ import pdb; pdb.set_trace() source = event.getSource() print 'APPLY button clicked. New configuration loaded.' global MAGIC_PARAMETER global PARAMETERISPOST global PARAMETERISGET global PARAMETERISCOOKIE global BASE64ENCODINGENABLED global ASCII2HEXENCODINGENABLED global URLENCODINGENABLED global INTRUDERENABLED global SCANNERENABLED MAGIC_PARAMETER=self.parameterName.getText() print 'Base64 checkbox is: '+str(self.base64Enabled.isSelected()) if self.base64Enabled.isSelected(): BASE64ENCODINGENABLED=True else: BASE64ENCODINGENABLED=False print 'ASCII2Hex checkbox is: '+str(self.ASCII2HexEnabled.isSelected()) if self.ASCII2HexEnabled.isSelected(): ASCII2HEXENCODINGENABLED=True else: ASCII2HEXENCODINGENABLED=False print 'URL checkbox is: '+str(self.URLEnabled.isSelected()) if self.URLEnabled.isSelected(): URLENCODINGENABLED=True else: URLENCODINGENABLED=False print 'New Magic parameter is: '+str(MAGIC_PARAMETER) if self.POSTparameterTypeRadioButton.isSelected(): #BODYPARAM PARAMETERISPOST=True print "parameterispost has been set to: " + str(PARAMETERISPOST) else: PARAMETERISPOST=False print "parameterispost has been set to: " + str(PARAMETERISPOST) if self.GETparameterTypeRadioButton.isSelected(): #GETPARAM PARAMETERISGET=True print "parameterisget has been set to: " + str(PARAMETERISGET) else: PARAMETERISGET=False print "parameterisget has been set to: " + str(PARAMETERISGET) if self.COOKIEparameterTypeRadioButton.isSelected(): #COOKIEPARAM PARAMETERISCOOKIE=True print "parameteriscookie has been set to: " + str(PARAMETERISCOOKIE) else: PARAMETERISCOOKIE=False print "parameteriscookie has been set to: " + str(PARAMETERISCOOKIE) if self.ScannerEnabled.isSelected(): SCANNERENABLED=True print "Scanner Enabled" else: SCANNERENABLED=False if self.IntruderEnabled.isSelected(): INTRUDERENABLED=True print "Intruder Enabled" else: INTRUDERENABLED=False # # implement IHTTPListener # def processHttpMessage(self, toolFlag, messageIsRequest, currentRequest): global PARAMETERISPOST global PARAMETERISGET global PARAMETERISCOOKIE global URLENCODINGENABLED global BASE64ENCODINGENABLED global ASCII2HEXENCODINGENABLED global INTRUDERENABLED global SCANNERENABLED #only process requests if not messageIsRequest: return #only process messages from Intruder and Scanner, otherwise exit #if (not self._callbacks.TOOL_INTRUDER == toolFlag): if ((not ((self._callbacks.TOOL_INTRUDER == toolFlag) and INTRUDERENABLED)) and (not ((self._callbacks.TOOL_SCANNER == toolFlag) and SCANNERENABLED))): #print "exiting- toolflag:"+str(toolFlag)+' INTRUDERENABLED='+str(INTRUDERENABLED)+' SCANNERENABLED='+str(SCANNERENABLED) return #if ((not self._callbacks.TOOL_INTRUDER == toolFlag)) and ((not self._callbacks.TOOL_SCANNER == toolFlag)):#remove the comment to always enable if DEBUG: print "IHTTPListener Enabled in: " + str(toolFlag) requestInfo = self._helpers.analyzeRequest(currentRequest) timestamp = datetime.now() if DEBUG: print "Intercepting message at: ", timestamp.isoformat() #parameters = requestInfo.getParameters() dataParameter = self._helpers.getRequestParameter(currentRequest.getRequest(), MAGIC_PARAMETER) #FIXME: add exception handling for multiple parameters with the same name and/or in a different position!!! if DEBUG: print 'dataparameter:'+str(dataParameter) if (dataParameter == None): if DEBUG: print 'Parameter does not exist' return serializedValue = dataParameter.getValue() #FIXME: substitute '[AND]' placeholder with '&' charachter - we should do something more elegant here :/ serializedValue = re.sub(r'\[AND\]', '&', serializedValue) print "unserialized parameter value: ", str(serializedValue) if BASE64ENCODINGENABLED: #if base64Encode is selected serializedValue = self._helpers.base64Encode(serializedValue) if DEBUG: print "base64 encoded parameter value: ", str(serializedValue) if URLENCODINGENABLED: #if URLEncode is selected serializedValue = self._helpers.urlEncode(serializedValue) if DEBUG: print "URL ecoded parameter value: ", str(serializedValue) if ASCII2HEXENCODINGENABLED: #if ASCII2HexEncode is selected serializedValue = convert_ascii2hex(serializedValue) if DEBUG: print "ASCII2Hex ecoded parameter value: ", str(serializedValue) print "serialized parameter value: ", serializedValue if PARAMETERISPOST: if DEBUG: print "parameter is BODY" currentRequest.setRequest(self._helpers.updateParameter(currentRequest.getRequest(),self._helpers.buildParameter(MAGIC_PARAMETER, serializedValue,IParameter.PARAM_BODY))) elif PARAMETERISGET: if DEBUG: print "parameter is in URL" currentRequest.setRequest(self._helpers.updateParameter(currentRequest.getRequest(),self._helpers.buildParameter(MAGIC_PARAMETER, serializedValue,IParameter.PARAM_URL))) elif PARAMETERISCOOKIE: if DEBUG: print "parameter is a COOKIE" currentRequest.setRequest(self._helpers.updateParameter(currentRequest.getRequest(),self._helpers.buildParameter(MAGIC_PARAMETER, serializedValue,IParameter.PARAM_COOKIE))) return # # implement ITab # def getTabCaption(self): global EXTENSION_TABCAPTION return(EXTENSION_TABCAPTION) def getUiComponent(self): #~ return self._splitpane return self.tab # # implement IMessageEditorTabFactory # def createNewInstance(self, controller, editable): # create a new instance of our custom editor tab return CustomInputTab(self, controller, editable)
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel): # # implement IBurpExtender # def registerExtenderCallbacks(self, callbacks): # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("Otter") # create the log and a lock on which to synchronize when adding log entries self._log = ArrayList() self._lock = Lock() # main split pane for log entries and request/response viewing self._settingPanel = JPanel() self._logPane = JSplitPane(JSplitPane.VERTICAL_SPLIT) # setup settings pane ui self._settingPanel.setBounds(0,0,1000,1000) self._settingPanel.setLayout(None) self._isRegexp = JCheckBox("Use regexp for matching.") self._isRegexp.setBounds(10, 10, 220, 20) matchLabel = JLabel("String to Match:") matchLabel.setBounds(10, 40, 200, 20) self._matchString = JTextArea("User 1 Session Information") self._matchString.setWrapStyleWord(True) self._matchString.setLineWrap(True) matchString = JScrollPane(self._matchString) matchString.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED) matchString.setBounds(10, 60, 400, 200) replaceLabel = JLabel("String to Replace:") replaceLabel.setBounds(10, 270, 200, 20) self._replaceString = JTextArea("User 2 Session Information") self._replaceString.setWrapStyleWord(True) self._replaceString.setLineWrap(True) replaceString = JScrollPane(self._replaceString) replaceString.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED) replaceString.setBounds(10, 290, 400, 200) self._settingPanel.add(self._isRegexp) self._settingPanel.add(matchLabel) self._settingPanel.add(matchString) self._settingPanel.add(replaceLabel) self._settingPanel.add(replaceString) # table of log entries logTable = Table(self) logTable.getColumnModel().getColumn(0).setPreferredWidth(700) logTable.getColumnModel().getColumn(1).setPreferredWidth(150) logTable.getColumnModel().getColumn(2).setPreferredWidth(100) logTable.getColumnModel().getColumn(3).setPreferredWidth(130) logTable.getColumnModel().getColumn(4).setPreferredWidth(100) logTable.getColumnModel().getColumn(5).setPreferredWidth(130) scrollPane = JScrollPane(logTable) self._logPane.setLeftComponent(scrollPane) # tabs with request/response viewers logTabs = JTabbedPane() self._origRequestViewer = callbacks.createMessageEditor(self, False) self._origResponseViewer = callbacks.createMessageEditor(self, False) self._modRequestViewer = callbacks.createMessageEditor(self, False) self._modResponseViewer = callbacks.createMessageEditor(self, False) logTabs.addTab("Original Request", self._origRequestViewer.getComponent()) logTabs.addTab("Original Response", self._origResponseViewer.getComponent()) logTabs.addTab("Modified Request", self._modRequestViewer.getComponent()) logTabs.addTab("Modified Response", self._modResponseViewer.getComponent()) self._logPane.setRightComponent(logTabs) # top most tab interface that seperates log entries from settings maintabs = JTabbedPane() maintabs.addTab("Log Entries", self._logPane) maintabs.addTab("Settings", self._settingPanel) self._maintabs = maintabs # customize the UI components callbacks.customizeUiComponent(maintabs) # add the custom tab to Burp's UI callbacks.addSuiteTab(self) # register ourselves as an HTTP listener callbacks.registerHttpListener(self) return # # implement ITab # def getTabCaption(self): return "Otter" def getUiComponent(self): return self._maintabs # # implement IHttpListener # def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): # Only process responses that came from the proxy. This will # ignore request/responses made by Otter itself. if not messageIsRequest and toolFlag == self._callbacks.TOOL_PROXY: # create a new log entry with the message details row = self._log.size() # analyze and store information about the original request/response responseBytes = messageInfo.getResponse() requestBytes = messageInfo.getRequest() request = self._helpers.analyzeRequest(messageInfo) response = self._helpers.analyzeResponse(responseBytes) # ignore out-of-scope requests. if not self._callbacks.isInScope(request.getUrl()): return wasModified = False ms = self._matchString.getText() rs = self._replaceString.getText() mss = ms.split(",") rss = rs.split(",") if len(rss) != len(mss): mss = [""] for i,x in enumerate(mss): if x == "": continue if self._isRegexp.isSelected(): if search(x, requestBytes): requestBytes = sub(x, rss[i], requestBytes) wasModified = True else: if fromBytes(requestBytes).find(x) >= 0: requestBytes = toBytes(replace(fromBytes(requestBytes), x, rss[i])) wasModified = True # make a modified request to test for authorization issues entry = None if wasModified: modReqResp = self._callbacks.makeHttpRequest(messageInfo.getHttpService(), requestBytes) modRequestBytes = modReqResp.getRequest() modResponseBytes = modReqResp.getResponse() modResponse = self._helpers.analyzeResponse(modResponseBytes) orig = self._callbacks.saveBuffersToTempFiles(messageInfo) mod = self._callbacks.saveBuffersToTempFiles(modReqResp) entry = LogEntry(orig, mod, request.getUrl(), response.getStatusCode(), len(responseBytes), modResponse.getStatusCode(), len(modResponseBytes), wasModified) else: orig = self._callbacks.saveBuffersToTempFiles(messageInfo) entry = LogEntry(orig, None, request.getUrl(), response.getStatusCode(), len(responseBytes), "None", 0, wasModified) self._lock.acquire() self._log.add(entry) self.fireTableRowsInserted(row, row) self._lock.release() return # # extend AbstractTableModel # def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 6 def getColumnName(self, columnIndex): if columnIndex == 0: return "URL" if columnIndex == 1: return "Request Modified?" if columnIndex == 2: return "Orig. Status" if columnIndex == 3: return "Orig. Length" if columnIndex == 4: return "Mod. Status" if columnIndex == 5: return "Mod. Length" return "" def getValueAt(self, rowIndex, columnIndex): logEntry = self._log.get(rowIndex) if columnIndex == 0: return logEntry._url.toString() if columnIndex == 1: return str(logEntry._wasModified) if columnIndex == 2: return str(logEntry._origStatus) if columnIndex == 3: return str(logEntry._origLength) if columnIndex == 4: return str(logEntry._modStatus) if columnIndex == 5: return str(logEntry._modLength) return "" # # implement IMessageEditorController # this allows our request/response viewers to obtain details about the messages being displayed # def getHttpService(self): return self._currentlyDisplayedItem.getHttpService() def getRequest(self): return self._currentlyDisplayedItem.getRequest() def getResponse(self): return self._currentlyDisplayedItem.getResponse()
class BurpExtender(IBurpExtender, ITab): def registerExtenderCallbacks(self, callbacks): print "Loading..." self._callbacks = callbacks self._callbacks.setExtensionName('Burp SSL Scanner') # self._callbacks.registerScannerCheck(self) # self._callbacks.registerExtensionStateListener(self) self._helpers = callbacks.getHelpers() # initialize the main scanning event and thread self.scanningEvent = Event() self.scannerThread = None self.targetURL = None # main split pane self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT) self._splitpane.setBorder(EmptyBorder(20, 20, 20, 20)) # sub split pane (top) self._topPanel = JPanel(BorderLayout(10, 10)) self._topPanel.setBorder(EmptyBorder(0, 0, 10, 0)) # Setup Panel : [Target: ] [______________________] [START BUTTON] self.setupPanel = JPanel(FlowLayout(FlowLayout.LEADING, 10, 10)) self.setupPanel.add( JLabel("Target:", SwingConstants.LEFT), BorderLayout.LINE_START) self.hostField = JTextField('', 50) self.setupPanel.add(self.hostField) self.toggleButton = JButton( 'Start scanning', actionPerformed=self.startScan) self.setupPanel.add(self.toggleButton) if 'Professional' in callbacks.getBurpVersion()[0] : self.addToSitemapCheckbox = JCheckBox('Add to sitemap', True) else : self.addToSitemapCheckbox = JCheckBox('Add to sitemap (requires Professional version)', False) self.addToSitemapCheckbox.setEnabled(False) self.setupPanel.add(self.addToSitemapCheckbox) self.scanSiteMapHostCheckbox = JCheckBox('Scan sitemap hosts', True) self.setupPanel.add(self.scanSiteMapHostCheckbox) self._topPanel.add(self.setupPanel, BorderLayout.PAGE_START) # Status bar self.scanStatusPanel = JPanel(FlowLayout(FlowLayout.LEADING, 10, 10)) self.scanStatusPanel.add(JLabel("Status: ", SwingConstants.LEFT)) self.scanStatusLabel = JLabel("Ready to scan", SwingConstants.LEFT) self.scanStatusPanel.add(self.scanStatusLabel) self._topPanel.add(self.scanStatusPanel, BorderLayout.LINE_START) self._splitpane.setTopComponent(self._topPanel) # bottom panel self._bottomPanel = JPanel(BorderLayout(10, 10)) self._bottomPanel.setBorder(EmptyBorder(10, 0, 0, 0)) self.initialText = ('<h1 style="color: red;">Burp SSL Scanner<br />' 'Please note that TLS1.3 is still not supported by this extension.</h1>') self.currentText = self.initialText self.textPane = JTextPane() self.textScrollPane = JScrollPane(self.textPane) self.textPane.setContentType("text/html") self.textPane.setText(self.currentText) self.textPane.setEditable(False) self._bottomPanel.add(self.textScrollPane, BorderLayout.CENTER) self.savePanel = JPanel(FlowLayout(FlowLayout.LEADING, 10, 10)) self.saveButton = JButton('Save to file', actionPerformed=self.saveToFile) self.saveButton.setEnabled(False) self.savePanel.add(self.saveButton) self.clearScannedHostButton = JButton('Clear scanned host', actionPerformed=self.clearScannedHost) self.savePanel.add(self.clearScannedHostButton) self.savePanel.add(JLabel("Clear hosts that were scanned by active scan to enable rescanning", SwingConstants.LEFT)) self._bottomPanel.add(self.savePanel, BorderLayout.PAGE_END) self._splitpane.setBottomComponent(self._bottomPanel) callbacks.customizeUiComponent(self._splitpane) callbacks.addSuiteTab(self) print "SSL Scanner tab loaded" self.scannerMenu = ScannerMenu(self) callbacks.registerContextMenuFactory(self.scannerMenu) print "SSL Scanner custom menu loaded" self.scannerCheck = ScannerCheck(self, self.scanSiteMapHostCheckbox.isSelected) callbacks.registerScannerCheck(self.scannerCheck) print "SSL Scanner check registered" projectConfig = json.loads(self._callbacks.saveConfigAsJson()) scanAccuracy = projectConfig['scanner']['active_scanning_optimization']['scan_accuracy'] scanSpeed = projectConfig['scanner']['active_scanning_optimization']['scan_speed'] print(scanAccuracy, scanSpeed) self.scannedHost = [] print 'SSL Scanner loaded' def startScan(self, ev) : host = self.hostField.text self.scanningEvent.set() if(len(host) == 0): return if host.find("://") == -1: host = "https://" + host try: self.targetURL = URL(host) if(self.targetURL.getPort() == -1): self.targetURL = URL("https", self.targetURL.getHost(), 443, "/") self.hostField.setEnabled(False) self.toggleButton.setEnabled(False) self.saveButton.setEnabled(False) self.addToSitemapCheckbox.setEnabled(False) self.currentText = self.initialText self.textPane.setText(self.currentText) self.updateText("<h2>Scanning %s:%d</h2>" % (self.targetURL.getHost(), self.targetURL.getPort())) print("Scanning %s:%d" % (self.targetURL.getHost(), self.targetURL.getPort())) self.scannerThread = Thread(target=self.scan, args=(self.targetURL, )) self.scannerThread.start() except BaseException as e: self.saveButton.setEnabled(False) print(e) return def scan(self, url, usingBurpScanner=False): def setScanStatusLabel(text) : if not usingBurpScanner : SwingUtilities.invokeLater( ScannerRunnable(self.scanStatusLabel.setText, (text,))) def updateResultText(text) : if not usingBurpScanner : SwingUtilities.invokeLater( ScannerRunnable(self.updateText, (text, ))) if usingBurpScanner : res = result.Result(url, self._callbacks, self._helpers, False) else : res = result.Result(url, self._callbacks, self._helpers, self.addToSitemapCheckbox.isSelected()) host, port = url.getHost(), url.getPort() ### Get project configuration projectConfig = json.loads(self._callbacks.saveConfigAsJson()) if 'scanner' in projectConfig: # scanAccuracy: minimise_false_negatives, normal, minimise_false_positives scanAccuracy = projectConfig['scanner']['active_scanning_optimization']['scan_accuracy'] # scanSpeed: fast, normal, thorough scanSpeed = projectConfig['scanner']['active_scanning_optimization']['scan_speed'] else: scanAccuracy = 'normal' scanSpeed = 'normal' updateResultText('<h2>Scanning speed: %s</h2> %s' % (scanSpeed, test_details.SCANNING_SPEED_INFO[scanSpeed])) updateResultText('<h2>Scanning accuracy: %s</h2> %s' % (scanAccuracy, test_details.SCANNING_ACCURACY_INFO[scanAccuracy])) try : setScanStatusLabel("Checking for supported SSL/TLS versions") con = connection_test.ConnectionTest(res, host, port, scanSpeed, scanAccuracy) con.start() conResultText = '<hr /><br /><h3>' + res.printResult('connectable') + '</h3>' + \ '<ul><li>' + res.printResult('offer_ssl2') + '</li>' + \ '<li>' + res.printResult('offer_ssl3') + '</li>' + \ '<li>' + res.printResult('offer_tls10') + '</li>' + \ '<li>' + res.printResult('offer_tls11') + '</li>' + \ '<li>' + res.printResult('offer_tls12') + '</li></ul>' updateResultText(conResultText) if not res.getResult('connectable') : updateResultText("<h2>Scan terminated (Connection failed)</h2>") raise BaseException('Connection failed') setScanStatusLabel("Checking for supported cipher suites (This can take a long time)") supportedCipher = supportedCipher_test.SupportedCipherTest(res, host, port, scanSpeed, scanAccuracy) supportedCipher.start() setScanStatusLabel("Checking for Cipherlist") cipher = cipher_test.CipherTest(res, host, port, scanSpeed, scanAccuracy) cipher.start() cipherResultText = '<h3>Available ciphers:</h3>' + \ '<ul><li>' + res.printResult('cipher_NULL') + '</li>' + \ '<li>' + res.printResult('cipher_ANON') + '</li>' + \ '<li>' + res.printResult('cipher_EXP') + '</li>' + \ '<li>' + res.printResult('cipher_LOW') + '</li>' + \ '<li>' + res.printResult('cipher_WEAK') + '</li>' + \ '<li>' + res.printResult('cipher_3DES') + '</li>' + \ '<li>' + res.printResult('cipher_HIGH') + '</li>' + \ '<li>' + res.printResult('cipher_STRONG') + '</li></ul>' updateResultText(cipherResultText) setScanStatusLabel("Checking for Heartbleed") heartbleed = heartbleed_test.HeartbleedTest(res, host, port, scanSpeed, scanAccuracy) heartbleed.start() heartbleedResultText = res.printResult('heartbleed') updateResultText(heartbleedResultText) setScanStatusLabel("Checking for CCS Injection") ccs = ccs_test.CCSTest(res, host, port, scanSpeed, scanAccuracy) ccs.start() ccsResultText = res.printResult('ccs_injection') updateResultText(ccsResultText) setScanStatusLabel("Checking for TLS_FALLBACK_SCSV") fallback = fallback_test.FallbackTest(res, host, port, scanSpeed, scanAccuracy) fallback.start() fallbackResultText = res.printResult('fallback_support') updateResultText(fallbackResultText) setScanStatusLabel("Checking for POODLE (SSLv3)") poodle = poodle_test.PoodleTest(res, host, port, scanSpeed, scanAccuracy) poodle.start() poodleResultText = res.printResult('poodle_ssl3') updateResultText(poodleResultText) setScanStatusLabel("Checking for SWEET32") sweet32 = sweet32_test.Sweet32Test(res, host, port, scanSpeed, scanAccuracy) sweet32.start() sweet32ResultText = res.printResult('sweet32') updateResultText(sweet32ResultText) setScanStatusLabel("Checking for DROWN") drown = drown_test.DrownTest(res, host, port, scanSpeed, scanAccuracy) drown.start() drownResultText = res.printResult('drown') updateResultText(drownResultText) setScanStatusLabel("Checking for FREAK") freak = freak_test.FreakTest(res, host, port, scanSpeed, scanAccuracy) freak.start() freakResultText = res.printResult('freak') updateResultText(freakResultText) setScanStatusLabel("Checking for LUCKY13") lucky13 = lucky13_test.Lucky13Test(res, host, port, scanSpeed, scanAccuracy) lucky13.start() lucky13ResultText = res.printResult('lucky13') updateResultText(lucky13ResultText) setScanStatusLabel("Checking for CRIME") crime = crime_test.CrimeTest(res, host, port, scanSpeed, scanAccuracy) crime.start() crimeResultText = res.printResult('crime_tls') updateResultText(crimeResultText) setScanStatusLabel("Checking for BREACH") breach = breach_test.BreachTest(res, host, port, scanSpeed, scanAccuracy) breach.start(self._callbacks, self._helpers) breachResultText = res.printResult('breach') updateResultText(breachResultText) setScanStatusLabel("Checking for BEAST") beast = beast_test.BeastTest(res, host, port, scanSpeed, scanAccuracy) beast.start() beastResultText = res.printResult('beast') updateResultText(beastResultText) setScanStatusLabel("Checking for LOGJAM") logjam = logjam_test.LogjamTest(res, host, port, scanSpeed, scanAccuracy) logjam.start() logjamResultText = res.printResult('logjam_export') + '<br />' + res.printResult('logjam_common') updateResultText(logjamResultText) updateResultText('<h2>Finished scanning</h2><br /><hr /><br /><h2>Summary</h2>') updateResultText('<h2>Supported ciphers (by Protocol)</h2>') updateResultText(res.printCipherList()) updateResultText('<h2>Supported ciphers (by Vulnerability)</h2>') updateResultText(res.printCipherListByVulns()) updateResultText('<h2>Issues found</h2>') updateResultText(res.printAllIssue()) except BaseException as e : print(e) setScanStatusLabel("An error occurred. Please refer to the output/errors tab for more information.") time.sleep(2) if usingBurpScanner : return res.getAllIssue() else : self.scanningEvent.clear() SwingUtilities.invokeLater( ScannerRunnable(self.toggleButton.setEnabled, (True, )) ) SwingUtilities.invokeLater( ScannerRunnable(self.hostField.setEnabled, (True, )) ) SwingUtilities.invokeLater( ScannerRunnable(self.saveButton.setEnabled, (True, )) ) if 'Professional' in self._callbacks.getBurpVersion()[0] : SwingUtilities.invokeLater( ScannerRunnable(self.addToSitemapCheckbox.setEnabled, (True, )) ) setScanStatusLabel("Ready to scan") print("Finished scanning") def updateText(self, stringToAppend): self.currentText += ('<br />' + stringToAppend) self.textPane.setText(self.currentText) def saveToFile(self, event): fileChooser = JFileChooser() if not (self.targetURL is None): fileChooser.setSelectedFile(File("Burp_SSL_Scanner_Result_%s.html" \ % (self.targetURL.getHost()))) else: fileChooser.setSelectedFile(File("Burp_SSL_Scanner_Result.html")) if (fileChooser.showSaveDialog(self.getUiComponent()) == JFileChooser.APPROVE_OPTION): fw = FileWriter(fileChooser.getSelectedFile()) fw.write(self.textPane.getText()) fw.flush() fw.close() print "Saved results to disk" def clearScannedHost(self, event) : self.scannedHost = [] def addHostToScannedList(self, host, port) : self.scannedHost.append([host, port]) def getTabCaption(self): return "SSL Scanner" def getUiComponent(self): return self._splitpane
class tag(ITab): def __init__(self, callbacks, name): self._callbacks = callbacks self.name = name def getTabCaption(self): return self.name def getUiComponent(self): return self.tabs def setFontItalic(self, label): label.setFont( Font(label.getFont().getName(), Font.ITALIC, label.getFont().getSize())) def setFontBold(self, label): label.setFont(Font('Serif', Font.BOLD, label.getFont().getSize())) # 配置界面添加 def tagLoad(self): # 创建窗口 开始 self.tabs = JTabbedPane() self.settings = JPanel(GridBagLayout()) self.forward_requests_settings = JPanel(GridBagLayout()) self.white_list_domain_settings = JPanel(GridBagLayout()) c = GridBagConstraints() # 界面选项卡1-标签加载 self.tag_1(c) self.tag_2(c) # 界面选项卡2-标签加载 self.tag_3(c) self.tag_4(c) # 界面选项卡3-标签加载 self.tag_5(c) # 添加选项卡 self.tabs.addTab(u'基本设置', self.settings) self.tabs.addTab(u'http请求转发设置', self.forward_requests_settings) self.tabs.addTab(u'白名单域名设置', self.white_list_domain_settings) self._callbacks.customizeUiComponent(self.tabs) self._callbacks.addSuiteTab(self) # 选项卡1-标签1-ui def tag_1(self, c): # 创建 检查框 self.is_start_box = JCheckBox(u'是否启动插件', ForwardRequestsConfig.IS_START) self.setFontBold(self.is_start_box) self.is_start_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 1 self.settings.add(self.is_start_box, c) # 在窗口添加一句话 is_start_box_lbl = JLabel(u'打勾-启动, 不打勾-关闭') self.setFontItalic(is_start_box_lbl) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 2 self.settings.add(is_start_box_lbl, c) # 选项卡1-标签1-值 def isStartBox(self): return self.is_start_box.isSelected() # 选项卡1-标签2-ui def tag_2(self, c): # 创建 检查框 self.url_repeated_box = JCheckBox( u'是否启动url重复验证', ForwardRequestsConfig.URL_REPEATED_VERIFY) self.setFontBold(self.url_repeated_box) self.url_repeated_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 3 self.settings.add(self.url_repeated_box, c) # 在窗口添加一句话 url_repeated_box_lbl = JLabel(u'打勾-开启验证, 不打勾-关闭验证') self.setFontItalic(url_repeated_box_lbl) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 4 self.settings.add(url_repeated_box_lbl, c) # 选项卡1-标签2-值 def urlRepeatedBox(self): return self.url_repeated_box.isSelected() # 选项卡2-标签1-ui def tag_3(self, c): # 创建 检查框 self.is_proxy_forward_requests_box = JCheckBox( u'是否启动Proxy模块请求转发(推荐打勾)', ForwardRequestsConfig.IS_START_PROXY_FORWARD_REQUESTS) self.setFontBold(self.is_proxy_forward_requests_box) self.is_proxy_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 1 self.forward_requests_settings.add(self.is_proxy_forward_requests_box, c) # 在窗口添加一句话 is_proxy_forward_requests_box_lbl = JLabel(u'打勾-启动, 不打勾-关闭') self.setFontItalic(is_proxy_forward_requests_box_lbl) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 2 self.forward_requests_settings.add(is_proxy_forward_requests_box_lbl, c) # 选项卡2-标签2-ui def tag_4(self, c): # 创建 检查框 self.is_repeater_forward_requests_box = JCheckBox( u'是否启动Repeater模块请求转发', ForwardRequestsConfig.IS_START_REPEATER_FORWARD_REQUESTS) self.setFontBold(self.is_repeater_forward_requests_box) self.is_repeater_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 3 self.forward_requests_settings.add( self.is_repeater_forward_requests_box, c) # 在窗口添加一句话 is_repeater_forward_requests_box_lbl = JLabel(u'打勾-启动, 不打勾-关闭') self.setFontItalic(is_repeater_forward_requests_box_lbl) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 4 self.forward_requests_settings.add( is_repeater_forward_requests_box_lbl, c) # 获取允许转发的burp模块列表 def getWhiteListModule(self): white_list_module = [] if self.is_proxy_forward_requests_box.isSelected(): white_list_module.append(4) if self.is_repeater_forward_requests_box.isSelected(): white_list_module.append(64) return white_list_module # 选项卡3-标签1-ui def tag_5(self, c): # 输入框-标题 lblParams = JLabel(u'请填写域名:') self.setFontBold(lblParams) lblParams.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 0 c.insets = Insets(5, 5, 5, 5) c.fill = GridBagConstraints.NONE c.anchor = GridBagConstraints.FIRST_LINE_END self.white_list_domain_settings.add(lblParams, c) # 输入框 self.white_list_text_field = JTextField() c.fill = GridBagConstraints.BOTH c.gridx = 1 c.gridy = 0 self.white_list_domain_settings.add(self.white_list_text_field, c) lblParamsNote = JLabel(u"白名单域名列表") self.setFontItalic(lblParamsNote) c.fill = GridBagConstraints.NONE c.gridx = 0 c.gridy = 1 self.white_list_domain_settings.add(lblParamsNote, c) # 添加 文本框 self.white_list_text_area = JTextArea() self.white_list_text_area.setColumns(20) self.white_list_text_area.setRows(10) self.white_list_text_area.setEditable(False) c.fill = GridBagConstraints.BOTH self.white_list_mouse_listener = TextAreaMouseListener( self.white_list_text_area) self.white_list_text_area.addMouseListener( self.white_list_mouse_listener) # 向文本框添加数据 for name in white_list_names: self.white_list_text_area.append(name + '\n' + os.linesep) c.gridx = 1 c.gridy = 1 sp = JScrollPane(self.white_list_text_area) self.white_list_domain_settings.add(sp, c) # 添加 删除 重置 buttonsPanel = JPanel(GridBagLayout()) _c = GridBagConstraints() _c.insets = Insets(3, 3, 3, 3) _c.gridx = 0 _c.fill = GridBagConstraints.BOTH _c.weightx = 1 _c.gridwidth = 1 handlers = ButtonHandlers(self.white_list_text_field, self.white_list_text_area, self.white_list_mouse_listener, white_list_names) # 添加按钮 self.white_list_add_button = JButton( u'添加', actionPerformed=handlers.handler_add) _c.gridy = 1 buttonsPanel.add(self.white_list_add_button, _c) # 删除按钮 self.white_list_rm_button = JButton( u'删除', actionPerformed=handlers.handler_rm) _c.gridy = 2 buttonsPanel.add(self.white_list_rm_button, _c) # 重置按钮 self.white_list_restore_button = JButton( u'重置', actionPerformed=handlers.handler_restore) _c.gridy = 3 buttonsPanel.add(self.white_list_restore_button, _c) c.gridx = 2 c.gridy = 1 c.fill = GridBagConstraints.NONE self.white_list_domain_settings.add(buttonsPanel, c) # 获取白名单域名列表 def getWhiteList(self): return self.text_area_to_list(self.white_list_text_area) # 获取指定text数据 def text_area_to_list(self, text_area): l = [] text_list = text_area.getText().strip().split('\n') for data in text_list: if data == '': continue data = data.replace("\n", '') data = data.replace("\r", '') data = data.strip(' ') l.append(data) return l
class BurpExtender(IBurpExtender, IHttpListener, IMessageEditorTabFactory, ITab): # # implement IBurpExtender # def registerExtenderCallbacks(self, callbacks): global EXTENSION_NAME sys.stdout = callbacks.getStdout() sys.stderr = callbacks.getStderr() # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName(EXTENSION_NAME) # register ourselves as a Http Listener callbacks.registerHttpListener(self) # register ourselves as a message editor tab factory callbacks.registerMessageEditorTabFactory(self) # setup the UI self.initGui() # add the custom tab to Burp's UI self._callbacks.addSuiteTab(self) return # # create the Gui # def initGui(self): #~ if DEBUG: #~ import pdb; #~ pdb.set_trace() tabPane = JTabbedPane(JTabbedPane.TOP) CreditsText = "<html># Burp Custom Deserializer<br/># Copyright (c) 2016, Marco Tinari<br/>#<br/># This program is free software: you can redistribute it and/or modify<br/># it under the terms of the GNU General Public License as published by<br/># the Free Software Foundation, either version 3 of the License, or<br/># (at your option) any later version.<br/>#<br/># This program is distributed in the hope that it will be useful,<br/># but WITHOUT ANY WARRANTY; without even the implied warranty of<br/># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br/># GNU General Public License for more details.<br/>#<br/># You should have received a copy of the GNU General Public License<br/># along with this program. If not, see <http://www.gnu.org/licenses/>.)<br/></html>" label1 = JLabel( "<html>Usage:<br>1 - Select the desired encoding functions<br>2 - Enter the name of the parameter in the input field below and press the Apply button!</html>" ) label2 = JLabel(CreditsText) panel1 = JPanel() #set layout panel1.setLayout(GridLayout(11, 1)) panel2 = JPanel() panel1.add(label1) panel2.add(label2) tabPane.addTab("Configuration", panel1) tabPane.addTab("Credits", panel2) applyButton = JButton('Apply', actionPerformed=self.reloadConf) panel1.add(applyButton, BorderLayout.SOUTH) #define GET/POST/COOKIE radio button self.GETparameterTypeRadioButton = JRadioButton('GET parameter') self.POSTparameterTypeRadioButton = JRadioButton('POST parameter') self.COOKIEparameterTypeRadioButton = JRadioButton('COOKIE parameter') self.POSTparameterTypeRadioButton.setSelected(True) group = ButtonGroup() group.add(self.GETparameterTypeRadioButton) group.add(self.POSTparameterTypeRadioButton) group.add(self.COOKIEparameterTypeRadioButton) self.base64Enabled = JCheckBox("Base64 encode") self.URLEnabled = JCheckBox("URL encode") self.ASCII2HexEnabled = JCheckBox("ASCII to Hex") self.ScannerEnabled = JCheckBox( "<html>Enable serialization in Burp Scanner<br>Usage:<br>1.Place unencoded values inside intruder request and define the placeholder positions<br>2.rightclick->Actively scan defined insertion points)</html>" ) self.IntruderEnabled = JCheckBox( "<html>Enable serialization in Burp Intruder<br>Usage:<br>1.Place unencoded values inside intruder request and define the placeholder positions<br>2.Start the attack</html>" ) self.parameterName = JTextField("Parameter name goes here...", 60) #set the tooltips self.parameterName.setToolTipText( "Fill in the parameter name and apply") self.base64Enabled.setToolTipText("Enable base64 encoding/decoding") self.ASCII2HexEnabled.setToolTipText( "Enable ASCII 2 Hex encoding/decoding") self.URLEnabled.setToolTipText("Enable URL encoding/decoding") self.IntruderEnabled.setToolTipText( "Check this if You want the extension to intercept and modify every request made by the Burp Intruder containing the selected paramter" ) self.ScannerEnabled.setToolTipText( "Check this if You want the extension to intercept and modify every request made by the Burp Scanner containing the selected paramter" ) #add checkboxes to the panel panel1.add(self.parameterName) panel1.add(self.POSTparameterTypeRadioButton) panel1.add(self.GETparameterTypeRadioButton) panel1.add(self.COOKIEparameterTypeRadioButton) panel1.add(self.base64Enabled) panel1.add(self.URLEnabled) panel1.add(self.ASCII2HexEnabled) panel1.add(self.IntruderEnabled) panel1.add(self.ScannerEnabled) #assign tabPane self.tab = tabPane def reloadConf(self, event): #~ if DEBUG: #~ import pdb; pdb.set_trace() source = event.getSource() print 'APPLY button clicked. New configuration loaded.' global MAGIC_PARAMETER global PARAMETERISPOST global PARAMETERISGET global PARAMETERISCOOKIE global BASE64ENCODINGENABLED global ASCII2HEXENCODINGENABLED global URLENCODINGENABLED global INTRUDERENABLED global SCANNERENABLED MAGIC_PARAMETER = self.parameterName.getText() print 'Base64 checkbox is: ' + str(self.base64Enabled.isSelected()) if self.base64Enabled.isSelected(): BASE64ENCODINGENABLED = True else: BASE64ENCODINGENABLED = False print 'ASCII2Hex checkbox is: ' + str( self.ASCII2HexEnabled.isSelected()) if self.ASCII2HexEnabled.isSelected(): ASCII2HEXENCODINGENABLED = True else: ASCII2HEXENCODINGENABLED = False print 'URL checkbox is: ' + str(self.URLEnabled.isSelected()) if self.URLEnabled.isSelected(): URLENCODINGENABLED = True else: URLENCODINGENABLED = False print 'New Magic parameter is: ' + str(MAGIC_PARAMETER) if self.POSTparameterTypeRadioButton.isSelected(): #BODYPARAM PARAMETERISPOST = True print "parameterispost has been set to: " + str(PARAMETERISPOST) else: PARAMETERISPOST = False print "parameterispost has been set to: " + str(PARAMETERISPOST) if self.GETparameterTypeRadioButton.isSelected(): #GETPARAM PARAMETERISGET = True print "parameterisget has been set to: " + str(PARAMETERISGET) else: PARAMETERISGET = False print "parameterisget has been set to: " + str(PARAMETERISGET) if self.COOKIEparameterTypeRadioButton.isSelected(): #COOKIEPARAM PARAMETERISCOOKIE = True print "parameteriscookie has been set to: " + str( PARAMETERISCOOKIE) else: PARAMETERISCOOKIE = False print "parameteriscookie has been set to: " + str( PARAMETERISCOOKIE) if self.ScannerEnabled.isSelected(): SCANNERENABLED = True print "Scanner Enabled" else: SCANNERENABLED = False if self.IntruderEnabled.isSelected(): INTRUDERENABLED = True print "Intruder Enabled" else: INTRUDERENABLED = False # # implement IHTTPListener # def processHttpMessage(self, toolFlag, messageIsRequest, currentRequest): global PARAMETERISPOST global PARAMETERISGET global PARAMETERISCOOKIE global URLENCODINGENABLED global BASE64ENCODINGENABLED global ASCII2HEXENCODINGENABLED global INTRUDERENABLED global SCANNERENABLED #only process requests if not messageIsRequest: return #only process messages from Intruder and Scanner, otherwise exit #if (not self._callbacks.TOOL_INTRUDER == toolFlag): if ((not ( (self._callbacks.TOOL_INTRUDER == toolFlag) and INTRUDERENABLED)) and (not ((self._callbacks.TOOL_SCANNER == toolFlag) and SCANNERENABLED))): #print "exiting- toolflag:"+str(toolFlag)+' INTRUDERENABLED='+str(INTRUDERENABLED)+' SCANNERENABLED='+str(SCANNERENABLED) return #if ((not self._callbacks.TOOL_INTRUDER == toolFlag)) and ((not self._callbacks.TOOL_SCANNER == toolFlag)):#remove the comment to always enable if DEBUG: print "IHTTPListener Enabled in: " + str(toolFlag) requestInfo = self._helpers.analyzeRequest(currentRequest) timestamp = datetime.now() if DEBUG: print "Intercepting message at: ", timestamp.isoformat() #parameters = requestInfo.getParameters() dataParameter = self._helpers.getRequestParameter( currentRequest.getRequest(), MAGIC_PARAMETER) #FIXME: add exception handling for multiple parameters with the same name and/or in a different position!!! if DEBUG: print 'dataparameter:' + str(dataParameter) if (dataParameter == None): if DEBUG: print 'Parameter does not exist' return serializedValue = dataParameter.getValue() #FIXME: substitute '[AND]' placeholder with '&' charachter - we should do something more elegant here :/ serializedValue = re.sub(r'\[AND\]', '&', serializedValue) print "unserialized parameter value: ", str(serializedValue) if BASE64ENCODINGENABLED: #if base64Encode is selected serializedValue = self._helpers.base64Encode(serializedValue) if DEBUG: print "base64 encoded parameter value: ", str(serializedValue) if URLENCODINGENABLED: #if URLEncode is selected serializedValue = self._helpers.urlEncode(serializedValue) if DEBUG: print "URL ecoded parameter value: ", str(serializedValue) if ASCII2HEXENCODINGENABLED: #if ASCII2HexEncode is selected serializedValue = convert_ascii2hex(serializedValue) if DEBUG: print "ASCII2Hex ecoded parameter value: ", str( serializedValue) print "serialized parameter value: ", serializedValue if PARAMETERISPOST: if DEBUG: print "parameter is BODY" currentRequest.setRequest( self._helpers.updateParameter( currentRequest.getRequest(), self._helpers.buildParameter(MAGIC_PARAMETER, serializedValue, IParameter.PARAM_BODY))) elif PARAMETERISGET: if DEBUG: print "parameter is in URL" currentRequest.setRequest( self._helpers.updateParameter( currentRequest.getRequest(), self._helpers.buildParameter(MAGIC_PARAMETER, serializedValue, IParameter.PARAM_URL))) elif PARAMETERISCOOKIE: if DEBUG: print "parameter is a COOKIE" currentRequest.setRequest( self._helpers.updateParameter( currentRequest.getRequest(), self._helpers.buildParameter(MAGIC_PARAMETER, serializedValue, IParameter.PARAM_COOKIE))) return # # implement ITab # def getTabCaption(self): global EXTENSION_TABCAPTION return (EXTENSION_TABCAPTION) def getUiComponent(self): #~ return self._splitpane return self.tab # # implement IMessageEditorTabFactory # def createNewInstance(self, controller, editable): # create a new instance of our custom editor tab return CustomInputTab(self, controller, editable)
class BeautifierOptionsPanel(JScrollPane): def __init__(self, extender): super(BeautifierOptionsPanel, self).__init__() self._extender = extender self.contentWrapper = JPanel(GridBagLayout()) self.setViewportView(self.contentWrapper) self.getVerticalScrollBar().setUnitIncrement(16) self.addMouseListener(self.RequestFocusListener( self)) # Let textArea lose focus when click empty area innerContainer = JPanel(GridBagLayout()) innerContainer.setFocusable( True ) # make sure the maxSizeText TextField is not focused when BeautifierOptionsPanel display # generalOptionPanel and it's inner component maxSizeLabel = JLabel("Max Size: ") self.maxSizeText = JTextField(5) self.maxSizeText.setHorizontalAlignment(SwingConstants.RIGHT) self.maxSizeText.addFocusListener(self.MaxSizeTextListener(self)) sizeUnitLabel = JLabel("KB") generalOptionPanel = JPanel(GridBagLayout()) generalOptionPanel.setBorder( BorderFactory.createTitledBorder("General Options")) gbc = GridBagConstraints() gbc.anchor = GridBagConstraints.WEST gbc.gridx = 0 gbc.gridy = 0 generalOptionPanel.add(maxSizeLabel, gbc) gbc.fill = GridBagConstraints.HORIZONTAL gbc.gridx = 1 gbc.gridy = 0 generalOptionPanel.add(self.maxSizeText, gbc) gbc.fill = GridBagConstraints.NONE gbc.gridx = 2 gbc.gridy = 0 gbc.weightx = 1.0 generalOptionPanel.add(sizeUnitLabel, gbc) gbc = GridBagConstraints() gbc.fill = GridBagConstraints.BOTH gbc.gridx = 1 gbc.gridy = 0 gbc.gridheight = 2 innerContainer.add(generalOptionPanel, gbc) # messageTabOptionPanel and it's inner component self.messageTabFormatCheckBoxs = [] for f in supportedFormats: ckb = JCheckBox(f) ckb.addItemListener(self.messageTabFormatListener) self.messageTabFormatCheckBoxs.append(ckb) messageTabOptionPanel = JPanel() messageTabOptionPanel.setLayout( BoxLayout(messageTabOptionPanel, BoxLayout.Y_AXIS)) messageTabOptionPanel.setBorder( BorderFactory.createTitledBorder("Enable in MessageEditorTab")) for b in self.messageTabFormatCheckBoxs: messageTabOptionPanel.add(b) gbc.gridx = 1 gbc.gridy = 2 gbc.gridheight = 9 innerContainer.add(messageTabOptionPanel, gbc) # replaceResponsePanel and it's inner component self.chkEnableReplace = JCheckBox("Enable") self.chkEnableReplace.addItemListener(self.repalceResponseBoxListener) replaceResponseFormatLabel = JLabel("Format") self.replaceResponseFormatCheckBoxs = [] for f in supportedFormats: ckb = JCheckBox(f) ckb.addItemListener(self.replaceResponseFormatListener) self.replaceResponseFormatCheckBoxs.append(ckb) replaceResponseIncludeLabel = JLabel( "Include URL that matches below(one item one line)") self.URLIncludeTextArea = JTextArea(6, 32) self.URLIncludeTextArea.addFocusListener( self.URLIncludeFocusListener(self)) URLIncludeScrollPane = JScrollPane(self.URLIncludeTextArea) URLIncludeScrollPane.setAlignmentX(Component.LEFT_ALIGNMENT) replaceResponseExcludeLabel = JLabel( "Exclude URL that matches below(one item one line)") self.URLExcludeTextArea = JTextArea(5, 32) self.URLExcludeTextArea.addFocusListener( self.URLExcludeFocusListener(self)) URLExcludeScrollPane = JScrollPane(self.URLExcludeTextArea) URLExcludeScrollPane.setAlignmentX(Component.LEFT_ALIGNMENT) replaceResponsePanel = JPanel() replaceResponsePanel.setLayout( BoxLayout(replaceResponsePanel, BoxLayout.Y_AXIS)) replaceResponsePanel.setBorder( BorderFactory.createTitledBorder("Replace PROXY Response")) replaceResponsePanel.add(self.chkEnableReplace) replaceResponsePanel.add(Box.createVerticalStrut(10)) replaceResponsePanel.add(replaceResponseFormatLabel) for b in self.replaceResponseFormatCheckBoxs: replaceResponsePanel.add(b) replaceResponsePanel.add(Box.createVerticalStrut(10)) replaceResponsePanel.add(replaceResponseIncludeLabel) replaceResponsePanel.add(URLIncludeScrollPane) replaceResponsePanel.add(Box.createVerticalStrut(10)) replaceResponsePanel.add(replaceResponseExcludeLabel) replaceResponsePanel.add(URLExcludeScrollPane) gbc.gridy = 11 innerContainer.add(replaceResponsePanel, gbc) # let innerContainer keep away from left and up gbc = GridBagConstraints() gbc.gridx = 1 gbc.gridy = 1 self.contentWrapper.add(Box.createHorizontalStrut(15), gbc) # gbc.ipadx = gbc.ipady = 25 gbc.gridx = 2 self.contentWrapper.add(innerContainer, gbc) # let innerContainer stay left side gbc = GridBagConstraints() gbc.gridx = 3 gbc.gridy = 2 gbc.gridwidth = 1 gbc.weightx = gbc.weighty = 1 paddingPanel = JPanel() self.contentWrapper.add(paddingPanel, gbc) self.setDefaultOptionDisplay() def disableReplaceResponseDisplay(self): for chb in self.replaceResponseFormatCheckBoxs: chb.setEnabled(False) self.URLIncludeTextArea.setEnabled(False) self.URLExcludeTextArea.setEnabled(False) def enableReplaceResponseDisplay(self): for chb in self.replaceResponseFormatCheckBoxs: chb.setEnabled(True) self.URLIncludeTextArea.setEnabled(True) self.URLExcludeTextArea.setEnabled(True) def setDefaultOptionDisplay(self): self.maxSizeText.setText( str(options.get("general").get("dataMaxSize") / 1024)) for chb in self.messageTabFormatCheckBoxs: format = chb.getText() chb.setSelected(options.get("messageEditorTabFormat").get(format)) self.chkEnableReplace.setSelected( options.get("replaceProxyResponse").get("enable")) for chb in self.replaceResponseFormatCheckBoxs: format = chb.getText() chb.setSelected( options.get("replaceProxyResponse").get("formats").get(format)) self.URLIncludeTextArea.setText("\n".join( options.get("replaceProxyResponse").get("include", []))) self.URLExcludeTextArea.setText("\n".join( options.get("replaceProxyResponse").get("exclude", []))) if self.chkEnableReplace.isSelected(): self.enableReplaceResponseDisplay() else: self.disableReplaceResponseDisplay() def saveOptions(self): if self._extender: self._extender._callbacks.saveExtensionSetting( "options", json.dumps(options)) class RequestFocusListener(MouseAdapter): def __init__(self, beautifierOptionsPanel): super(BeautifierOptionsPanel.RequestFocusListener, self).__init__() self.beautifierOptionsPanel = beautifierOptionsPanel def mouseClicked(self, e): self.beautifierOptionsPanel.requestFocusInWindow() class MaxSizeTextListener(FocusListener): def __init__(self, beautifierOptionsPanel): super(BeautifierOptionsPanel.MaxSizeTextListener, self).__init__() self.beautifierOptionsPanel = beautifierOptionsPanel def focusGained(self, e): pass def focusLost(self, e): size = e.getSource().getText() try: size = int(float(size)) options.get("general").update({"dataMaxSize": size * 1024}) e.getSource().setText(str(size)) self.beautifierOptionsPanel.saveOptions() except: e.getSource().setText( str(options.get("general").get("dataMaxSize") / 1024)) def messageTabFormatListener(self, e): format = e.getSource().getText() if e.getStateChange() == ItemEvent.SELECTED: options.get("messageEditorTabFormat").update({format: True}) else: options.get("messageEditorTabFormat").update({format: False}) self.saveOptions() def repalceResponseBoxListener(self, e): if e.getStateChange() == ItemEvent.SELECTED: options.get("replaceProxyResponse").update({"enable": True}) self.enableReplaceResponseDisplay() else: options.get("replaceProxyResponse").update({"enable": False}) self.disableReplaceResponseDisplay() self.saveOptions() def replaceResponseFormatListener(self, e): format = e.getSource().getText() if e.getStateChange() == ItemEvent.SELECTED: options.get("replaceProxyResponse").get("formats").update( {format: True}) else: options.get("replaceProxyResponse").get("formats").update( {format: False}) self.saveOptions() class URLIncludeFocusListener(FocusListener): def __init__(self, beautifierOptionsPanel): super(BeautifierOptionsPanel.URLIncludeFocusListener, self).__init__() self.beautifierOptionsPanel = beautifierOptionsPanel def focusGained(self, e): pass def focusLost(self, e): text = e.getSource().getText() # <unicode> urlPatterns = [ p.strip() for p in text.split("\n") if p.strip() != "" ] options.get("replaceProxyResponse").update( {"include": urlPatterns}) self.beautifierOptionsPanel.saveOptions() class URLExcludeFocusListener(FocusListener): def __init__(self, beautifierOptionsPanel): super(BeautifierOptionsPanel.URLExcludeFocusListener, self).__init__() self.beautifierOptionsPanel = beautifierOptionsPanel def focusGained(self, e): pass def focusLost(self, e): text = e.getSource().getText() # <unicode> urlPatterns = [ p.strip() for p in text.split("\n") if p.strip() != "" ] options.get("replaceProxyResponse").update( {"exclude": urlPatterns}) self.beautifierOptionsPanel.saveOptions()
class tag(ITab): def __init__(self, callbacks, name): self._callbacks = callbacks self.name = name def getTabCaption(self): return self.name def getUiComponent(self): return self.tabs def setFontItalic(self, label): label.setFont( Font(label.getFont().getName(), Font.ITALIC, label.getFont().getSize())) def setFontBold(self, label): label.setFont(Font('Serif', Font.BOLD, label.getFont().getSize())) # 配置界面添加 def tagLoad(self): # 创建窗口 开始 self.tabs = JTabbedPane() self.settings = JPanel(GridBagLayout()) self.forward_requests_settings = JPanel(GridBagLayout()) self.white_list_domain_settings = JPanel(GridBagLayout()) self.white_list_http_method_settings = JPanel(GridBagLayout()) c = GridBagConstraints() # 界面选项卡1-标签加载 self.tag_1_1(c) self.tag_1_2(c) # 界面选项卡2-标签加载 self.tag_2_1(c) self.tag_2_2(c) # 界面选项卡3-标签加载 self.tag_3_1(c) # 界面选项卡4-标签加载 self.tag_4_1(c) self.tag_4_2(c) self.tag_4_3(c) self.tag_4_4(c) self.tag_4_5(c) self.tag_4_6(c) self.tag_4_7(c) self.tag_4_8(c) self.tag_4_9(c) self.tag_4_10(c) self.tag_4_11(c) self.tag_4_12(c) self.tag_4_13(c) self.tag_4_14(c) self.tag_4_15(c) # 添加选项卡 self.tabs.addTab(u'基本设置', self.settings) self.tabs.addTab(u'http请求转发设置', self.forward_requests_settings) self.tabs.addTab(u'白名单域名设置', self.white_list_domain_settings) self.tabs.addTab(u'白名单http方法设置', self.white_list_http_method_settings) self._callbacks.customizeUiComponent(self.tabs) self._callbacks.addSuiteTab(self) # 选项卡1-标签1-ui def tag_1_1(self, c): # 创建 检查框 self.is_start_box = JCheckBox(u'是否启动插件', ForwardRequestsConfig.IS_START) self.setFontBold(self.is_start_box) self.is_start_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 1 self.settings.add(self.is_start_box, c) # 在窗口添加一句话 is_start_box_lbl = JLabel(u'打勾-启动, 不打勾-关闭') self.setFontItalic(is_start_box_lbl) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 2 self.settings.add(is_start_box_lbl, c) # 选项卡1-标签1-值 def isStartBox(self): return self.is_start_box.isSelected() # 选项卡1-标签2-ui def tag_1_2(self, c): # 创建 检查框 self.url_repeated_box = JCheckBox( u'是否启动url重复验证', ForwardRequestsConfig.URL_REPEATED_VERIFY) self.setFontBold(self.url_repeated_box) self.url_repeated_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 3 self.settings.add(self.url_repeated_box, c) # 在窗口添加一句话 url_repeated_box_lbl = JLabel(u'打勾-开启验证, 不打勾-关闭验证') self.setFontItalic(url_repeated_box_lbl) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 4 self.settings.add(url_repeated_box_lbl, c) # 选项卡1-标签2-值 def urlRepeatedBox(self): return self.url_repeated_box.isSelected() # 选项卡2-标签1-ui def tag_2_1(self, c): # 创建 检查框 self.is_proxy_forward_requests_box = JCheckBox( u'是否启动Proxy模块请求转发(推荐打勾)', ForwardRequestsConfig.IS_START_PROXY_FORWARD_REQUESTS) self.setFontBold(self.is_proxy_forward_requests_box) self.is_proxy_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 1 self.forward_requests_settings.add(self.is_proxy_forward_requests_box, c) # 在窗口添加一句话 is_proxy_forward_requests_box_lbl = JLabel(u'打勾-启动, 不打勾-关闭') self.setFontItalic(is_proxy_forward_requests_box_lbl) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 2 self.forward_requests_settings.add(is_proxy_forward_requests_box_lbl, c) # 选项卡2-标签2-ui def tag_2_2(self, c): # 创建 检查框 self.is_repeater_forward_requests_box = JCheckBox( u'是否启动Repeater模块请求转发', ForwardRequestsConfig.IS_START_REPEATER_FORWARD_REQUESTS) self.setFontBold(self.is_repeater_forward_requests_box) self.is_repeater_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 3 self.forward_requests_settings.add( self.is_repeater_forward_requests_box, c) # 在窗口添加一句话 is_repeater_forward_requests_box_lbl = JLabel(u'打勾-启动, 不打勾-关闭') self.setFontItalic(is_repeater_forward_requests_box_lbl) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 4 self.forward_requests_settings.add( is_repeater_forward_requests_box_lbl, c) # 获取允许转发的burp模块列表 def getWhiteListModule(self): white_list_module = [] if self.is_proxy_forward_requests_box.isSelected(): white_list_module.append(4) if self.is_repeater_forward_requests_box.isSelected(): white_list_module.append(64) return white_list_module # 选项卡3-标签1-ui def tag_3_1(self, c): # 输入框-标题 lblParams = JLabel(u'请填写域名:') self.setFontBold(lblParams) lblParams.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 0 c.insets = Insets(5, 5, 5, 5) c.fill = GridBagConstraints.NONE c.anchor = GridBagConstraints.FIRST_LINE_END self.white_list_domain_settings.add(lblParams, c) # 输入框 self.white_list_text_field = JTextField() c.fill = GridBagConstraints.BOTH c.gridx = 1 c.gridy = 0 self.white_list_domain_settings.add(self.white_list_text_field, c) lblParamsNote = JLabel(u"白名单域名列表") self.setFontItalic(lblParamsNote) c.fill = GridBagConstraints.NONE c.gridx = 0 c.gridy = 1 self.white_list_domain_settings.add(lblParamsNote, c) # 添加 文本框 self.white_list_text_area = JTextArea() self.white_list_text_area.setColumns(20) self.white_list_text_area.setRows(10) self.white_list_text_area.setEditable(False) c.fill = GridBagConstraints.BOTH self.white_list_mouse_listener = TextAreaMouseListener( self.white_list_text_area) self.white_list_text_area.addMouseListener( self.white_list_mouse_listener) # 向文本框添加数据 for name in white_list_names: self.white_list_text_area.append(name + '\n' + os.linesep) c.gridx = 1 c.gridy = 1 sp = JScrollPane(self.white_list_text_area) self.white_list_domain_settings.add(sp, c) # 添加 删除 重置 buttonsPanel = JPanel(GridBagLayout()) _c = GridBagConstraints() _c.insets = Insets(3, 3, 3, 3) _c.gridx = 0 _c.fill = GridBagConstraints.BOTH _c.weightx = 1 _c.gridwidth = 1 handlers = ButtonHandlers(self.white_list_text_field, self.white_list_text_area, self.white_list_mouse_listener, white_list_names) # 添加按钮 self.white_list_add_button = JButton( u'添加', actionPerformed=handlers.handler_add) _c.gridy = 1 buttonsPanel.add(self.white_list_add_button, _c) # 删除按钮 self.white_list_rm_button = JButton( u'删除', actionPerformed=handlers.handler_rm) _c.gridy = 2 buttonsPanel.add(self.white_list_rm_button, _c) # 重置按钮 self.white_list_restore_button = JButton( u'重置', actionPerformed=handlers.handler_restore) _c.gridy = 3 buttonsPanel.add(self.white_list_restore_button, _c) c.gridx = 2 c.gridy = 1 c.fill = GridBagConstraints.NONE self.white_list_domain_settings.add(buttonsPanel, c) # 获取白名单域名列表 def getWhiteList(self): return self.text_area_to_list(self.white_list_text_area) # 获取指定text数据 def text_area_to_list(self, text_area): l = [] text_list = text_area.getText().strip().split('\n') for data in text_list: if data == '': continue data = data.replace("\n", '') data = data.replace("\r", '') data = data.strip(' ') l.append(data) return l # 选项卡4-标签1-ui def tag_4_1(self, c): # 创建 检查框 self.is_get_forward_requests_box = JCheckBox( u'转发GET请求', ForwardRequestsConfig.IS_GET_FORWARD_REQUESTS) self.setFontBold(self.is_get_forward_requests_box) self.is_get_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 1 self.white_list_http_method_settings.add( self.is_get_forward_requests_box, c) # 选项卡4-标签2-ui def tag_4_2(self, c): # 创建 检查框 self.is_post_forward_requests_box = JCheckBox( u'转发POST请求', ForwardRequestsConfig.IS_POST_FORWARD_REQUESTS) self.setFontBold(self.is_post_forward_requests_box) self.is_post_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 2 self.white_list_http_method_settings.add( self.is_post_forward_requests_box, c) # 选项卡4-标签3-ui def tag_4_3(self, c): # 创建 检查框 self.is_put_forward_requests_box = JCheckBox( u'转发PUT请求', ForwardRequestsConfig.IS_PUT_FORWARD_REQUESTS) self.setFontBold(self.is_put_forward_requests_box) self.is_put_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 3 self.white_list_http_method_settings.add( self.is_put_forward_requests_box, c) # 选项卡4-标签4-ui def tag_4_4(self, c): # 创建 检查框 self.is_patch_forward_requests_box = JCheckBox( u'转发PATCH请求', ForwardRequestsConfig.IS_PATCH_FORWARD_REQUESTS) self.setFontBold(self.is_patch_forward_requests_box) self.is_patch_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 4 self.white_list_http_method_settings.add( self.is_patch_forward_requests_box, c) # 选项卡4-标签5-ui def tag_4_5(self, c): # 创建 检查框 self.is_delete_forward_requests_box = JCheckBox( u'转发DELETE请求', ForwardRequestsConfig.IS_DELETE_FORWARD_REQUESTS) self.setFontBold(self.is_delete_forward_requests_box) self.is_delete_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 5 self.white_list_http_method_settings.add( self.is_delete_forward_requests_box, c) # 选项卡4-标签6-ui def tag_4_6(self, c): # 创建 检查框 self.is_copy_forward_requests_box = JCheckBox( u'转发COPY请求', ForwardRequestsConfig.IS_COPY_FORWARD_REQUESTS) self.setFontBold(self.is_copy_forward_requests_box) self.is_copy_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 6 self.white_list_http_method_settings.add( self.is_copy_forward_requests_box, c) # 选项卡4-标签7-ui def tag_4_7(self, c): # 创建 检查框 self.is_head_forward_requests_box = JCheckBox( u'转发HEAD请求', ForwardRequestsConfig.IS_HEAD_FORWARD_REQUESTS) self.setFontBold(self.is_head_forward_requests_box) self.is_head_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 7 self.white_list_http_method_settings.add( self.is_head_forward_requests_box, c) # 选项卡4-标签8-ui def tag_4_8(self, c): # 创建 检查框 self.is_options_forward_requests_box = JCheckBox( u'转发OPTIONS请求', ForwardRequestsConfig.IS_OPTIONS_FORWARD_REQUESTS) self.setFontBold(self.is_options_forward_requests_box) self.is_options_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 8 self.white_list_http_method_settings.add( self.is_options_forward_requests_box, c) # 选项卡4-标签9-ui def tag_4_9(self, c): # 创建 检查框 self.is_link_forward_requests_box = JCheckBox( u'转发LINK请求', ForwardRequestsConfig.IS_LINK_FORWARD_REQUESTS) self.setFontBold(self.is_link_forward_requests_box) self.is_link_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 9 self.white_list_http_method_settings.add( self.is_link_forward_requests_box, c) # 选项卡4-标签10-ui def tag_4_10(self, c): # 创建 检查框 self.is_unlink_forward_requests_box = JCheckBox( u'转发UNLINK请求', ForwardRequestsConfig.IS_UNLINK_FORWARD_REQUESTS) self.setFontBold(self.is_unlink_forward_requests_box) self.is_unlink_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 10 self.white_list_http_method_settings.add( self.is_unlink_forward_requests_box, c) # 选项卡4-标签11-ui def tag_4_11(self, c): # 创建 检查框 self.is_purge_forward_requests_box = JCheckBox( u'转发PURGE请求', ForwardRequestsConfig.IS_PURGE_FORWARD_REQUESTS) self.setFontBold(self.is_purge_forward_requests_box) self.is_purge_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 11 self.white_list_http_method_settings.add( self.is_purge_forward_requests_box, c) # 选项卡4-标签12-ui def tag_4_12(self, c): # 创建 检查框 self.is_lock_forward_requests_box = JCheckBox( u'转发LOCK请求', ForwardRequestsConfig.IS_LOCK_FORWARD_REQUESTS) self.setFontBold(self.is_lock_forward_requests_box) self.is_lock_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 12 self.white_list_http_method_settings.add( self.is_lock_forward_requests_box, c) # 选项卡4-标签13-ui def tag_4_13(self, c): # 创建 检查框 self.is_unlock_forward_requests_box = JCheckBox( u'转发UNLOCK请求', ForwardRequestsConfig.IS_UNLOCK_FORWARD_REQUESTS) self.setFontBold(self.is_unlock_forward_requests_box) self.is_unlock_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 13 self.white_list_http_method_settings.add( self.is_unlock_forward_requests_box, c) # 选项卡4-标签14-ui def tag_4_14(self, c): # 创建 检查框 self.is_propfind_forward_requests_box = JCheckBox( u'转发PROPFIND请求', ForwardRequestsConfig.IS_PROPFIND_FORWARD_REQUESTS) self.setFontBold(self.is_propfind_forward_requests_box) self.is_propfind_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 14 self.white_list_http_method_settings.add( self.is_propfind_forward_requests_box, c) # 选项卡4-标签15-ui def tag_4_15(self, c): # 创建 检查框 self.is_view_forward_requests_box = JCheckBox( u'转发VIEW请求', ForwardRequestsConfig.IS_VIEW_FORWARD_REQUESTS) self.setFontBold(self.is_view_forward_requests_box) self.is_view_forward_requests_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 15 self.white_list_http_method_settings.add( self.is_view_forward_requests_box, c) # 获取白名单http方法 def getWhiteListHttpMethod(self): l = [] if self.is_get_forward_requests_box.isSelected(): l.append('GET') if self.is_post_forward_requests_box.isSelected(): l.append('POST') if self.is_put_forward_requests_box.isSelected(): l.append('PUT') if self.is_patch_forward_requests_box.isSelected(): l.append('PATCH') if self.is_delete_forward_requests_box.isSelected(): l.append('DELETE') if self.is_copy_forward_requests_box.isSelected(): l.append('COPY') if self.is_head_forward_requests_box.isSelected(): l.append('HEAD') if self.is_options_forward_requests_box.isSelected(): l.append('OPTIONS') if self.is_link_forward_requests_box.isSelected(): l.append('LINK') if self.is_unlink_forward_requests_box.isSelected(): l.append('UNLINK') if self.is_purge_forward_requests_box.isSelected(): l.append('PURGE') if self.is_lock_forward_requests_box.isSelected(): l.append('LOCK') if self.is_unlock_forward_requests_box.isSelected(): l.append('UNLOCK') if self.is_propfind_forward_requests_box.isSelected(): l.append('PROPFIND') if self.is_view_forward_requests_box.isSelected(): l.append('VIEW') return l
class NewAccountGUI: def __init__(self, amgui): self.amgui = amgui self.am = amgui.acctmanager self.buildgwinfo() self.autologin = JCheckBox("Automatically Log In") self.acctname = JTextField() self.gwoptions = JPanel(doublebuffered) self.gwoptions.border = TitledBorder("Gateway Options") self.buildgwoptions("Twisted") self.mainframe = JFrame("New Account Window") self.buildpane() def buildgwinfo(self): self.gateways = { "Twisted": { "ident": JTextField(), "passwd": JPasswordField(), "host": JTextField("twistedmatrix.com"), "port": JTextField("8787"), "service": JTextField("twisted.words"), "persp": JTextField(), }, "AIM": { "ident": JTextField(), "passwd": JPasswordField(), "host": JTextField("toc.oscar.aol.com"), "port": JTextField("9898"), }, "IRC": { "ident": JTextField(), "passwd": JPasswordField(), "host": JTextField(), "port": JTextField("6667"), "channels": JTextField(), }, } self.displayorder = { "Twisted": [ ["Identity Name", "ident"], ["Password", "passwd"], ["Host", "host"], ["Port", "port"], ["Service Name", "service"], ["Perspective Name", "persp"], ], "AIM": [["Screen Name", "ident"], ["Password", "passwd"], ["Host", "host"], ["Port", "port"]], "IRC": [ ["Nickname", "ident"], ["Password", "passwd"], ["Host", "host"], ["Port", "port"], ["Channels", "channels"], ], } def buildgwoptions(self, gw): self.gwoptions.removeAll() self.gwoptions.layout = GridLayout(len(self.gateways[gw]), 2) for mapping in self.displayorder[gw]: self.gwoptions.add(JLabel(mapping[0])) self.gwoptions.add(self.gateways[gw][mapping[1]]) def buildpane(self): gw = JPanel(GridLayout(1, 2), doublebuffered) gw.add(JLabel("Gateway")) self.gwlist = JComboBox(self.gateways.keys()) # , actionPerformed=self.changegw) self.gwlist.setSelectedItem("Twisted") gw.add(self.gwlist) stdoptions = JPanel(GridLayout(2, 2), doublebuffered) stdoptions.border = TitledBorder("Standard Options") stdoptions.add(JLabel()) stdoptions.add(self.autologin) stdoptions.add(JLabel("Account Name")) stdoptions.add(self.acctname) buttons = JPanel(FlowLayout(), doublebuffered) buttons.add(JButton("OK", actionPerformed=self.addaccount)) buttons.add(JButton("Cancel", actionPerformed=self.cancel)) mainpane = self.mainframe.getContentPane() mainpane.layout = BoxLayout(mainpane, BoxLayout.Y_AXIS) mainpane.add(gw) mainpane.add(self.gwoptions) mainpane.add(stdoptions) mainpane.add(buttons) def show(self): self.mainframe.setLocation(100, 100) self.mainframe.pack() self.mainframe.show() # actionlisteners def changegw(self, ae): self.buildgwoptions(self.gwlist.getSelectedItem()) self.mainframe.pack() self.mainframe.show() def addaccount(self, ae): gwselection = self.gwlist.getSelectedItem() gw = self.gateways[gwselection] name = gw["ident"].text passwd = gw["passwd"].text host = gw["host"].text port = int(gw["port"].text) autologin = self.autologin.isSelected() acctname = self.acctname.text if gwselection == "Twisted": sname = gw["service"].text perspective = gw["persp"].text self.am.addAccount(PBAccount(acctname, autologin, name, passwd, host, port, [[stype, sname, perspective]])) elif gwselection == "AIM": self.am.addAccount(TOCAccount(acctname, autologin, name, passwd, host, port)) elif gwselection == "IRC": channels = gw["channels"].text self.am.addAccount(IRCAccount(acctname, autologin, name, passwd, host, port, channels)) self.amgui.update() print "Added new account" self.mainframe.dispose() def cancel(self, ae): print "Cancelling new account creation" self.mainframe.dispose()
class JTabbedPaneClass: #判断域名返回IP地址 def getIp(self, domain): domain = domain.split(":")[0] ipExpression = re.compile('^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') domainExpression = re.compile("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$") if ipExpression.match(domain): return domain elif domainExpression.match(domain): myAddr = socket.getaddrinfo(domain,'http')[0][4][0] return myAddr else: return "domain error" #提取域名或IP信息 def getDomain1(self, theDomain): domain1 = theDomain.split(":")[0] return domain1 def __init__(self): frame = JFrame("S1riu5 Spy") frame.setSize(700, 690) frame.setLocationRelativeTo(None); frame.setLayout(BorderLayout()) tabPane = JTabbedPane(JTabbedPane.TOP) #第一个Tab用来做C段查询 eachIp = self.getIp(HOSTDOMAIN) iList = eachIp.split(".") theIP = iList[0] + "." + iList[1] + "." + iList[2] + ".1/24" panel1 = JPanel() label = JLabel("IP CIDR:") self.textfield1 = JTextField(theIP, 15) button = JButton("SCAN", actionPerformed = self.cNmapScan) self.textArea = JTextArea(40, 65) self.textArea.append("IP: " + eachIp) self.textArea.setLineWrap(True) #激活自动换行功能 self.textArea.setWrapStyleWord(True); # 激活断行不断字功能 panel1.add(label) panel1.add(self.textfield1) panel1.add(button) panel1.add(JScrollPane(self.textArea)) #设置自动滚动条 tabPane.addTab("C segment query ", panel1) #第二个Tab用来做子域名查询 theName = self.getDomain1(HOSTDOMAIN) self.textArea2 = JTextArea(40, 65) #self.textArea.append("IP: " + eachIp) self.textArea2.setLineWrap(True) #激活自动换行功能 self.textArea2.setWrapStyleWord(True) # 激活断行不断字功能 label2 = JLabel("Domain: ") self.textfield2 = JTextField(theName, 15) button2 = JButton("SCAN", actionPerformed = self.subDomain) self.panel2 = JPanel() self.panel2.add(label2) self.panel2.add(self.textfield2) self.panel2.add(button2) #self.panel2.add(scrollPane) self.panel2.add(JScrollPane(self.textArea2)) tabPane.addTab("subDomains", self.panel2) #第三个Tab用来做敏感文件扫描 self.tableData0 = [["1", "2"]] colNames2 = ('url','http code') dataModel3 = DefaultTableModel(self.tableData0, colNames2) self.table3 = JTable(dataModel3) ## label3 = JLabel("URL: ") self.textfield3 = JTextField(HOSTDOMAIN, 15) self.textArea3 = JTextArea(40, 65) #self.textArea.append("IP: " + eachIp) self.textArea3.setLineWrap(True) #激活自动换行功能 self.textArea3.setWrapStyleWord(True) # 激活断行不断字功能 a = 0 b = 0 self.label4 = JLabel(str(a) + "/" + str(b)) # self.chkbox1 = JCheckBox('ASP') self.chkbox2 = JCheckBox('ASPX') self.chkbox3 = JCheckBox('JSP') self.chkbox4 = JCheckBox('PHP') self.chkbox5 = JCheckBox('MDB') self.chkbox6 = JCheckBox('DIR') button3 = JButton("SCAN", actionPerformed = self.senFileScan) panel3 = JPanel() panel3.add(label3) panel3.add(self.textfield3) panel3.add(self.chkbox1) panel3.add(self.chkbox2) panel3.add(self.chkbox3) panel3.add(self.chkbox4) panel3.add(self.chkbox5) panel3.add(self.chkbox6) panel3.add(button3) panel3.add(self.label4) panel3.add(JScrollPane(self.textArea3)) # tabPane.addTab("Sebsitive File", panel3) # frame.add(tabPane) frame.setVisible(True) #用来在第一个TAB打印nmap信息 def setResult(self,text): self.textArea.append(text) #用来在第二个TAB打印获得信息 def setResult2(self,textId, textDomain, textIp): text = str(textId) + "----------------" + textDomain + "----------------" + str(textIp) + os.linesep self.textArea2.append(text) #self.textArea2.append("----------------------------------------" + os.linesep) #用来在第三个TAB打印文件扫描的结果 def setResult3(self, theMess01): self.textArea3.append(theMess01) def setLabel(self, a, b): hg = str(a) + "/" + str(b) self.label4.setText(hg) #C段扫描的主引擎 def cNmapScan(self, event): self.textArea.setText("") #------------------------------------------------------------------------------- def ipRange(ipaddr): """ Creates a generator that iterates through all of the IP addresses. The range can be specified in multiple formats. "192.168.1.0-192.168.1.255" : beginning-end "192.168.1.0/24" : CIDR "192.168.1.*" : wildcard """ def ipaddr_to_binary(ipaddr): """ A useful routine to convert a ipaddr string into a 32 bit long integer """ # from Greg Jorgensens python mailing list message q = ipaddr.split('.') return reduce(lambda a,b: long(a)*256 + long(b), q) #------------------------------------------------------------------------------- def binary_to_ipaddr(ipbinary): """ Convert a 32-bit long integer into an ipaddr dotted-quad string """ # This one is from Rikard Bosnjakovic return socket.inet_ntoa(struct.pack('!I', ipbinary)) def ipaddr_to_binary(ipaddr): """ A useful routine to convert a ipaddr string into a 32 bit long integer """ # from Greg Jorgensens python mailing list message q = ipaddr.split('.') return reduce(lambda a,b: long(a)*256 + long(b), q) #------------------------------------------------------------------------------- def binary_to_ipaddr(ipbinary): """ Convert a 32-bit long integer into an ipaddr dotted-quad string """ # This one is from Rikard Bosnjakovic return socket.inet_ntoa(struct.pack('!I', ipbinary)) #------------------------------------------------------------------------------- def cidr_iprange(ipaddr, cidrmask): """ Creates a generator that iterated through all of the IP addresses in a range given in CIDR notation """ # Get all the binary one's mask = (long(2)**long(32-long(cidrmask))) - 1 b = ipaddr_to_binary(ipaddr) e = ipaddr_to_binary(ipaddr) b = long(b & ~mask) e = long(e | mask) while (b <= e): yield binary_to_ipaddr(b) b = b + 1 #------------------------------------------------------------------------------- def wildcard_iprange(ipaddr): """ Creates a generator that iterates through all of the IP address in a range given with wild card notation """ beginning = [] end = [] tmp = ipaddr.split('.') for i in tmp: if i == '*': beginning.append("0") end.append("255") else: beginning.append(i) end.append(i) b = beginning[:] e = end[:] while int(b[0]) <= int(e[0]): while int(b[1]) <= int(e[1]): while int(b[2]) <= int(e[2]): while int(b[3]) <= int(e[3]): yield b[0] + '.' + b[1] + '.' + b[2] + '.' + b[3] b[3] = "%d" % (int(b[3]) + 1) b[2] = "%d" % (int(b[2]) + 1) b[3] = beginning[3] b[1] = "%d" % (int(b[1]) + 1) b[2] = beginning[2] b[0] = "%d" % (int(b[0]) + 1) b[1] = beginning[1] # Did we get the IP address in the span format? span_re = re.compile(r'''(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) # The beginning IP Address \s*-\s* (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) # The end IP Address ''', re.VERBOSE) res = span_re.match(ipaddr) if res: beginning = res.group(1) end = res.group(2) return span_iprange(beginning, end) # Did we get the IP address in the CIDR format? cidr_re = re.compile(r'''(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) # The IP Address /(\d{1,2}) # The mask ''', re.VERBOSE) res = cidr_re.match(ipaddr) if res: addr = res.group(1) cidrmask = res.group(2) return cidr_iprange(addr, cidrmask) # Did we get the IP address in the wildcard format? wild_re = re.compile(r'''(\d{1,3}|\*)\. (\d{1,3}|\*)\. (\d{1,3}|\*)\. (\d{1,3}|\*) # The IP Address ''', re.VERBOSE) res = wild_re.match(ipaddr) if res: return wildcard_iprange(ipaddr) return "The ip address given to ipaddr is improperly formatted" ipCidr = self.textfield1.getText() domainExpression = re.compile("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$") if domainExpression.match(ipCidr): JOptionPane.showMessageDialog(None, "You must enter IP", "s1riu5", JOptionPane.INFORMATION_MESSAGE) else: ipList = list(ipRange(ipCidr)) print len(ipList) if len(ipList) == 256: del ipList[0] del ipList[254] global NMAPPATH scan=ScanList(ipList, self, [NMAPPATH,"-Pn", "-sT", "-sV", "--open"]) scan.start() def subDomain(self, event): print self.textfield2.getText() b = subDomainThread(self.textfield2.getText(), self) b.start() def senFileScan(self, event): #print "Hello" urlListASP = ["/admin.asp"] urlListASPX = ["/admin.aspx"] urlListJSP = ["/admin.jsp"] urlListPHP = ["/admin.php"] urlListMDB = ["/admin.mdb"] urlListDIR = ["/admin/"] if self.chkbox1.isSelected(): domainTextObj1 = open("path/ASP.txt", "r") for each1 in domainTextObj1.readlines(): each1 = each1.strip() urlListASP.append(each1) domainTextObj1.close() if self.chkbox2.isSelected(): domainTextObj2 = open("path/ASPX.txt", "r") for each2 in domainTextObj2.readlines(): each2 = each2.strip() urlListASPX.append(each2) domainTextObj2.close() if self.chkbox3.isSelected(): domainTextObj3 = open("path/JSP.txt", "r") for each3 in domainTextObj3.readlines(): each3 = each3.strip() urlListJSP.append(each3) domainTextObj3.close() if self.chkbox4.isSelected(): domainTextObj4 = open("path/PHP.txt", "r") for each4 in domainTextObj4.readlines(): each4 = each4.strip() urlListPHP.append(each4) domainTextObj4.close() if self.chkbox5.isSelected(): domainTextObj5 = open("path/MDB.txt", "r") for each5 in domainTextObj5.readlines(): each5 = each5.strip() urlListMDB.append(each5) domainTextObj5.close() if self.chkbox6.isSelected(): domainTextObj6 = open("path/DIR.txt", "r") for each6 in domainTextObj6.readlines(): each6 = each6.strip() urlListDIR.append(each6) domainTextObj6.close() app = [] app = urlListASP + urlListASPX + urlListJSP + urlListPHP + urlListMDB + urlListDIR app1 = list(set(app)) theUrlText = self.textfield3.getText() #if str(theUrlText[0 : 7]) == "http://": # theUrlText = "http://" + theUrlText print len(app1) print len(app) #fileObj1 = eachFileScan(theUrlText, app) #fileObj1.start() ab = numControl(theUrlText, app1, self) ab.start()
class VadCheckModuleSettingsPanel(IngestModuleIngestJobSettingsPanel): # Note, we can't use a self.settings instance variable. # Rather, self.local_settings is used. # https://wiki.python.org/jython/UserGuide#javabean-properties # Jython Introspector generates a property - 'settings' on the basis # of getSettings() defined in this class. Since only getter function # is present, it creates a read-only 'settings' property. This auto- # generated read-only property overshadows the instance-variable - # 'settings' # We get passed in a previous version of the settings so that we can # prepopulate the UI # TODO: Update this for your UI def __init__(self, settings): #print("init: " + settings.getSetting("runVadTranscriber") + " " + settings.getSetting("minPercVoiced") + " " + settings.getSetting("minTotalVoiced")) #print("init local_settings: " + self.local_settings.getSetting("vadAggressivness") + " " + self.local_settings.getSetting("minPercVoiced") + " " + self.local_settings.getSetting("minTotalVoiced")) self.local_settings = GenericIngestModuleJobSettings() #initComponents will initialize sliders which will call lambdas for updating settings using current values in sliders #which would overwrite settings. self.initComponents() #print("init local_settings 2: " + self.local_settings.getSetting("vadAggressivness") + " " + self.local_settings.getSetting("minPercVoiced") + " " + self.local_settings.getSetting("minTotalVoiced")) #now safe to set settings self.local_settings = settings #print("init 2: " + self.local_settings.getSetting("runVadTranscriber") + " " + self.local_settings.getSetting("minPercVoiced") + " " + self.local_settings.getSetting("minTotalVoiced")) self.customizeComponents() _logger = Logger.getLogger(VadCheckModuleFactory.moduleName) def log(self, level, msg): self._logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg) # def makeGuiCallback(self, key, guiGetAction): # def callback(event): # #self.log(Level.INFO, "setting key = " + key + " val =" + str(event.getSource().getValue())) # value = str(guiGetAction(event.getSource())) # print("setting key = " + key + " val =" + value) # self.local_settings.setSetting(key, value) # print("test in settings key = " + key + " val =" + self.local_settings.getSetting(key)) # return callback def initComponents(self): #print("initComponents 1: " + self.local_settings.getSetting("vadAggressivness") + " " + self.local_settings.getSetting("minPercVoiced") + " " + self.local_settings.getSetting("minTotalVoiced")) self.setLayout(BoxLayout(self, BoxLayout.Y_AXIS)) self.label2 = JLabel() self.label2.setText("Minimum percentage of segments with speech") self.label3 = JLabel() self.label3.setText("Minimum total duration of segment with speech (s)") #sliderGetAction = lambda slider: slider.getValue() self.minPercVoiced = JSlider()#stateChanged=self.makeGuiCallback("minPercVoiced", sliderGetAction)) self.minPercVoiced.setMajorTickSpacing(20) self.minPercVoiced.setMinorTickSpacing(5) self.minPercVoiced.setPaintLabels(True) self.minPercVoiced.setPaintTicks(True) self.minTotalVoiced = JSlider()#stateChanged=self.makeGuiCallback("minTotalVoiced", sliderGetAction)) self.minTotalVoiced.setMajorTickSpacing(60) self.minTotalVoiced.setMaximum(180) self.minTotalVoiced.setMinorTickSpacing(10) self.minTotalVoiced.setPaintLabels(True) self.minTotalVoiced.setPaintTicks(True) #print("initComponents 2: " + self.local_settings.getSetting("vadAggressivness") + " " + self.local_settings.getSetting("minPercVoiced") + " " + self.local_settings.getSetting("minTotalVoiced")) #checkboxGetAction = lambda checkbox: checkbox.isSelected() self.runVadTranscriber = JCheckBox("Transcribe files with speech detected ? (slow)")#, #actionPerformed=self.makeGuiCallback("runVadTranscriber", checkboxGetAction)) self.showTextSegmentStartTime = JCheckBox("Show text segment start time ?") self.add(self.label2) self.add(self.minPercVoiced) self.add(self.label3) self.add(self.minTotalVoiced) self.add(self.showTextSegmentStartTime) self.add(self.runVadTranscriber) self.vadTranscriberLanguage = makeLanguageSelectionComboBox(self, "english") #this is needed because of https://bugs.jython.org/issue1749824 #class ComboActionListener(ActionListener): # def actionPerformed(self, e): # value = e.getSource().getSelectedItem() # self.local_settings.setSetting(key, value) #self.vadTranscriberLanguage.actionListener = ComboActionListener() #local_settings is of type https://github.com/sleuthkit/autopsy/blob/bbdea786db487c781edf2cf9032a2ba3166e97e0/Core/src/org/sleuthkit/autopsy/ingest/GenericIngestModuleJobSettings.java def customizeComponents(self): def setValue(key, default, stringToPythonObj, guiSetAction): string = self.local_settings.getSetting(key) #print("customizeComponents " + key + " stored value was " + str(string)) #print("string is None " + str(string is None) + " stringToPythonObj(string) " + str(stringToPythonObj(string))) checkedValue = default if string is None else stringToPythonObj(string) obj = getattr(self, key) guiSetAction(obj, checkedValue) #self.log(Level.INFO, "setValue for key " + key + " " + str(checkedValue)) sliderSetAction = lambda obj, val: obj.setValue(val) checkBoxSetAction = lambda obj, val: obj.setSelected(val) comboBoxSetAction = lambda obj, val: obj.setSelectedItem(val) setValue("minPercVoiced", minPercVoicedDefault, int, sliderSetAction) setValue("minTotalVoiced", minTotalVoicedDefault, int, sliderSetAction) setValue("runVadTranscriber", runVadTranscriberDefault, eval, checkBoxSetAction) setValue("showTextSegmentStartTime", showTextSegmentStartTimeDefault, eval, checkBoxSetAction) setValue("vadTranscriberLanguage", runVadTranscriberDefault, lambda x: x, comboBoxSetAction) # Return the settings used #note: exceptions thrown here will be caught and not logged. def getSettings(self): #print("getSettings: " + self.local_settings.getSetting("runVadTranscriber") + " " + self.local_settings.getSetting("minPercVoiced") + " " + self.local_settings.getSetting("minTotalVoiced")) self.local_settings.setSetting("minPercVoiced", str(self.minPercVoiced.getValue())) self.local_settings.setSetting("minTotalVoiced", str(self.minTotalVoiced.getValue())) self.local_settings.setSetting("runVadTranscriber", str(self.runVadTranscriber.isSelected())) self.local_settings.setSetting("showTextSegmentStartTime", str(self.showTextSegmentStartTime.isSelected())) self.local_settings.setSetting("vadTranscriberLanguage", str(self.vadTranscriberLanguage.getSelectedItem())) return self.local_settings
class BurpExtender(IBurpExtender, IProxyListener, ITab): def getTabCaption(self): ### ITab return NAME def getUiComponent(self): ### ITab return self.tabs def setFontItalic(self, label): label.setFont( Font(label.getFont().getName(), Font.ITALIC, label.getFont().getSize())) def setFontBold(self, label): label.setFont(Font('Serif', Font.BOLD, label.getFont().getSize())) def registerExtenderCallbacks(self, this_callbacks): ### IBurpExtender global callbacks, helpers global extension_enable, in_scope_only global change_method_to_post callbacks = this_callbacks helpers = callbacks.getHelpers() callbacks.setExtensionName(NAME) self.settings = JPanel(GridBagLayout()) c = GridBagConstraints() self.extension_enable_box = JCheckBox('Enable extension', extension_enable) self.setFontBold(self.extension_enable_box) self.extension_enable_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 0 c.gridwidth = 1 c.weightx = 1 c.fill = GridBagConstraints.NONE c.anchor = GridBagConstraints.WEST self.settings.add(self.extension_enable_box, c) self.in_scope_only_box = JCheckBox('Modify only in-scope requests', in_scope_only) self.setFontBold(self.in_scope_only_box) self.in_scope_only_box.setForeground(Color(0, 0, 153)) c.insets = Insets(40, 5, 5, 5) c.gridx = 0 c.gridy = 1 self.settings.add(self.in_scope_only_box, c) self.change_method_to_post_box = JCheckBox( 'Change HTTP method to POST', change_method_to_post) self.setFontBold(self.change_method_to_post_box) self.change_method_to_post_box.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 6 self.settings.add(self.change_method_to_post_box, c) change_method_to_post_lbl = JLabel( 'Check to convert PUT/DELETE/PATCH method to POST in all requests.' ) self.setFontItalic(change_method_to_post_lbl) c.gridx = 0 c.gridy = 7 self.settings.add(change_method_to_post_lbl, c) self.change_to_get_box = JCheckBox('Change to GET', change_to_get) self.setFontBold(self.change_to_get_box) self.change_to_get_box.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 12 self.settings.add(self.change_to_get_box, c) change_to_get_lbl = JLabel( 'Check to convert POST/PUT/DELETE/PATCH url-encoded requests to GET.' ) self.setFontItalic(change_to_get_lbl) c.gridx = 0 c.gridy = 13 self.settings.add(change_to_get_lbl, c) self.tabs = JTabbedPane() self.tabs.addTab('Settings', self.settings) callbacks.customizeUiComponent(self.tabs) callbacks.addSuiteTab(self) callbacks.registerProxyListener(self) print "Successfully loaded %s v%s by Mohammed alsaggaf " % (NAME, VERSION) def text_area_to_list(self, text_area): l = text_area.getText().strip().split('\n') return l if l != [''] else [] def processProxyMessage(self, messageIsRequest, message): ### IProxyListener global callbacks extension_enable = self.extension_enable_box.isSelected() if not extension_enable: return # Do nothing in_scope_only = self.in_scope_only_box.isSelected() change_method_to_post = self.change_method_to_post_box.isSelected() change_to_get = self.change_to_get_box.isSelected() request_response = message.getMessageInfo() request_info = helpers.analyzeRequest(request_response) request_method = request_info.getMethod() if in_scope_only and not callbacks.isInScope(request_info.getUrl()): return # Do nothing when URL is not in scope if not messageIsRequest or request_method not in [ 'POST', 'PUT', 'DELETE', 'PATCH' ]: return # Do nothing http_service = request_response.getHttpService() request = request_response.getRequest() headers = request_info.getHeaders() parameters = request_info.getParameters() new_headers = headers #new added offset = helpers.analyzeRequest(http_service, request).getBodyOffset() body = request[offset:] body = re.sub(",\s*,", ",", body) body = re.sub("{\s*,", "{", body) body = re.sub(",\s*}", "}", body) request = helpers.buildHttpMessage(headers, body) offset = helpers.analyzeRequest(http_service, request).getBodyOffset() body = request[offset:] #new Added if (change_method_to_post and request_method != 'POST') or (change_to_get and \ request_info.getContentType() == IRequestInfo.CONTENT_TYPE_URL_ENCODED): for i in range(len(new_headers)): if new_headers[i].startswith("PUT") or new_headers[i].startswith("DELETE") \ or new_headers[i].startswith("PATCH"): new_headers[i] = new_headers[i].replace( request_method, 'POST', 1) break new_request = helpers.buildHttpMessage( new_headers, body) # Create new request with valid Content-Length if (change_method_to_post and request_method != 'POST') or (change_to_get and \ request_info.getContentType() == IRequestInfo.CONTENT_TYPE_URL_ENCODED): param1 = helpers.buildParameter('method', request_method, IParameter.PARAM_URL) param2 = helpers.buildParameter('_method', request_method, IParameter.PARAM_URL) new_request = helpers.addParameter(new_request, param1) new_request = helpers.addParameter(new_request, param2) if change_to_get: new_request = helpers.toggleRequestMethod( new_request) # Change any URL-encoded request to GET self._callbacks.addToSiteMap(request_response) message.setInterceptAction( IInterceptedProxyMessage.ACTION_FOLLOW_RULES_AND_REHOOK) message.getMessageInfo().setRequest(new_request) message.getMessageInfo().setHighlight('red') self._callbacks.addToSiteMap(request_response)
class ConfigurableConfigPanel(ConfigPanel, ActionListener, DocumentListener, ChangeListener): """ generated source for class ConfigurableConfigPanel """ serialVersionUID = 1L associatedFile = File() associatedFileField = JTextField() params = JSONObject() savedParams = str() loadButton = JButton() saveAsButton = JButton() saveButton = JButton() name = JTextField() strategy = JComboBox() metagameStrategy = JComboBox() stateMachine = JComboBox() cacheStateMachine = JCheckBox() maxPlys = JSpinner() heuristicFocus = JSpinner() heuristicMobility = JSpinner() heuristicOpponentFocus = JSpinner() heuristicOpponentMobility = JSpinner() mcDecayRate = JSpinner() rightPanel = JPanel() def __init__(self): """ generated source for method __init__ """ super(ConfigurableConfigPanel, self).__init__(GridBagLayout()) leftPanel = JPanel(GridBagLayout()) leftPanel.setBorder(TitledBorder("Major Parameters")) self.rightPanel = JPanel(GridBagLayout()) self.rightPanel.setBorder(TitledBorder("Minor Parameters")) self.strategy = JComboBox([None]*) self.metagameStrategy = JComboBox([None]*) self.stateMachine = JComboBox([None]*) self.cacheStateMachine = JCheckBox() self.maxPlys = JSpinner(SpinnerNumberModel(1, 1, 100, 1)) self.heuristicFocus = JSpinner(SpinnerNumberModel(1, 0, 10, 1)) self.heuristicMobility = JSpinner(SpinnerNumberModel(1, 0, 10, 1)) self.heuristicOpponentFocus = JSpinner(SpinnerNumberModel(1, 0, 10, 1)) self.heuristicOpponentMobility = JSpinner(SpinnerNumberModel(1, 0, 10, 1)) self.mcDecayRate = JSpinner(SpinnerNumberModel(0, 0, 99, 1)) self.name = JTextField() self.name.setColumns(20) self.name.setText("Player #" + Random().nextInt(100000)) self.loadButton = JButton(loadButtonMethod()) self.saveButton = JButton(saveButtonMethod()) self.saveAsButton = JButton(saveAsButtonMethod()) self.associatedFileField = JTextField() self.associatedFileField.setEnabled(False) buttons = JPanel() buttons.add(self.loadButton) buttons.add(self.saveButton) buttons.add(self.saveAsButton) nRow = 0 leftPanel.add(JLabel("Name"), GridBagConstraints(0, nRow, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) __nRow_0 = nRow nRow += 1 leftPanel.add(self.name, GridBagConstraints(1, __nRow_0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, Insets(5, 5, 5, 5), 5, 5)) leftPanel.add(JLabel("Gaming Strategy"), GridBagConstraints(0, nRow, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) __nRow_1 = nRow nRow += 1 leftPanel.add(self.strategy, GridBagConstraints(1, __nRow_1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, Insets(5, 5, 5, 5), 5, 5)) leftPanel.add(JLabel("Metagame Strategy"), GridBagConstraints(0, nRow, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) __nRow_2 = nRow nRow += 1 leftPanel.add(self.metagameStrategy, GridBagConstraints(1, __nRow_2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, Insets(5, 5, 5, 5), 5, 5)) leftPanel.add(JLabel("State Machine"), GridBagConstraints(0, nRow, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) __nRow_3 = nRow nRow += 1 leftPanel.add(self.stateMachine, GridBagConstraints(1, __nRow_3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, Insets(5, 5, 5, 5), 5, 5)) __nRow_4 = nRow nRow += 1 leftPanel.add(buttons, GridBagConstraints(1, __nRow_4, 2, 1, 1.0, 1.0, GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, Insets(5, 5, 0, 5), 0, 0)) leftPanel.add(self.associatedFileField, GridBagConstraints(0, nRow, 2, 1, 1.0, 0.0, GridBagConstraints.SOUTHEAST, GridBagConstraints.HORIZONTAL, Insets(0, 5, 5, 5), 0, 0)) layoutRightPanel() add(leftPanel, GridBagConstraints(0, 0, 1, 1, 0.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, Insets(5, 5, 5, 5), 5, 5)) add(self.rightPanel, GridBagConstraints(1, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, Insets(5, 5, 5, 5), 5, 5)) self.params = JSONObject() syncJSONtoUI() self.strategy.addActionListener(self) self.metagameStrategy.addActionListener(self) self.stateMachine.addActionListener(self) self.cacheStateMachine.addActionListener(self) self.maxPlys.addChangeListener(self) self.heuristicFocus.addChangeListener(self) self.heuristicMobility.addChangeListener(self) self.heuristicOpponentFocus.addChangeListener(self) self.heuristicOpponentMobility.addChangeListener(self) self.mcDecayRate.addChangeListener(self) self.name.getDocument().addDocumentListener(self) def layoutRightPanel(self): """ generated source for method layoutRightPanel """ nRow = 0 self.rightPanel.removeAll() self.rightPanel.add(JLabel("State machine cache?"), GridBagConstraints(0, nRow, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) __nRow_5 = nRow nRow += 1 self.rightPanel.add(self.cacheStateMachine, GridBagConstraints(1, __nRow_5, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) if self.strategy.getSelectedItem().__str__() == "Heuristic": __nRow_6 = nRow nRow += 1 __nRow_7 = nRow nRow += 1 __nRow_8 = nRow nRow += 1 __nRow_9 = nRow nRow += 1 __nRow_10 = nRow nRow += 1 self.rightPanel.add(JLabel("Max plys?"), GridBagConstraints(0, nRow, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) self.rightPanel.add(self.maxPlys, GridBagConstraints(1, __nRow_6, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) self.rightPanel.add(JLabel("Focus Heuristic Weight"), GridBagConstraints(0, nRow, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) self.rightPanel.add(self.heuristicFocus, GridBagConstraints(1, __nRow_7, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) self.rightPanel.add(JLabel("Mobility Heuristic Weight"), GridBagConstraints(0, nRow, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) self.rightPanel.add(self.heuristicMobility, GridBagConstraints(1, __nRow_8, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) self.rightPanel.add(JLabel("Opponent Focus Heuristic Weight"), GridBagConstraints(0, nRow, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) self.rightPanel.add(self.heuristicOpponentFocus, GridBagConstraints(1, __nRow_9, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) self.rightPanel.add(JLabel("Opponent Mobility Heuristic Weight"), GridBagConstraints(0, nRow, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) self.rightPanel.add(self.heuristicOpponentMobility, GridBagConstraints(1, __nRow_10, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) if self.strategy.getSelectedItem().__str__() == "Monte Carlo": __nRow_11 = nRow nRow += 1 self.rightPanel.add(JLabel("Goal Decay Rate"), GridBagConstraints(0, nRow, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) self.rightPanel.add(self.mcDecayRate, GridBagConstraints(1, __nRow_11, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) __nRow_12 = nRow nRow += 1 self.rightPanel.add(JLabel(), GridBagConstraints(2, __nRow_12, 1, 1, 1.0, 1.0, GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE, Insets(5, 5, 5, 5), 5, 5)) self.rightPanel.repaint() @SuppressWarnings("unchecked") def getParameter(self, name, defaultValue): """ generated source for method getParameter """ try: if self.params.has(name): return self.params.get(name) else: return defaultValue except JSONException as je: return defaultValue def actionPerformed(self, arg0): """ generated source for method actionPerformed """ if arg0.getSource() == self.strategy: self.layoutRightPanel() syncJSONtoUI() def changedUpdate(self, e): """ generated source for method changedUpdate """ syncJSONtoUI() def insertUpdate(self, e): """ generated source for method insertUpdate """ syncJSONtoUI() def removeUpdate(self, e): """ generated source for method removeUpdate """ syncJSONtoUI() def stateChanged(self, arg0): """ generated source for method stateChanged """ syncJSONtoUI() def syncJSONtoUI(self): """ generated source for method syncJSONtoUI """ if settingUI: return self.params = getJSONfromUI() self.saveButton.setEnabled(self.savedParams == None or not self.params.__str__() == self.savedParams) def getJSONfromUI(self): """ generated source for method getJSONfromUI """ newParams = JSONObject() try: if not self.name.getText().isEmpty(): newParams.put("name", self.name.getText()) newParams.put("strategy", self.strategy.getSelectedItem().__str__()) newParams.put("metagameStrategy", self.metagameStrategy.getSelectedItem().__str__()) newParams.put("stateMachine", self.stateMachine.getSelectedItem().__str__()) newParams.put("cacheStateMachine", self.cacheStateMachine.isSelected()) newParams.put("maxPlys", self.maxPlys.getModel().getValue()) newParams.put("heuristicFocus", self.heuristicFocus.getModel().getValue()) newParams.put("heuristicMobility", self.heuristicMobility.getModel().getValue()) newParams.put("heuristicOpponentFocus", self.heuristicOpponentFocus.getModel().getValue()) newParams.put("heuristicOpponentMobility", self.heuristicOpponentMobility.getModel().getValue()) newParams.put("mcDecayRate", self.mcDecayRate.getModel().getValue()) except JSONException as je: je.printStackTrace() return newParams settingUI = False def setUIfromJSON(self): """ generated source for method setUIfromJSON """ self.settingUI = True try: if self.params.has("name"): self.name.setText(self.params.getString("name")) if self.params.has("strategy"): self.strategy.setSelectedItem(self.params.getString("strategy")) if self.params.has("metagameStrategy"): self.metagameStrategy.setSelectedItem(self.params.getString("metagameStrategy")) if self.params.has("stateMachine"): self.stateMachine.setSelectedItem(self.params.getString("stateMachine")) if self.params.has("cacheStateMachine"): self.cacheStateMachine.setSelected(self.params.getBoolean("cacheStateMachine")) if self.params.has("maxPlys"): self.maxPlys.getModel().setValue(self.params.getInt("maxPlys")) if self.params.has("heuristicFocus"): self.heuristicFocus.getModel().setValue(self.params.getInt("heuristicFocus")) if self.params.has("heuristicMobility"): self.heuristicMobility.getModel().setValue(self.params.getInt("heuristicMobility")) if self.params.has("heuristicOpponentFocus"): self.heuristicOpponentFocus.getModel().setValue(self.params.getInt("heuristicOpponentFocus")) if self.params.has("heuristicOpponentMobility"): self.heuristicOpponentMobility.getModel().setValue(self.params.getInt("heuristicOpponentMobility")) if self.params.has("mcDecayRate"): self.mcDecayRate.getModel().setValue(self.params.getInt("mcDecayRate")) except JSONException as je: je.printStackTrace() finally: self.settingUI = False def loadParamsJSON(self, fromFile): """ generated source for method loadParamsJSON """ if not fromFile.exists(): return self.associatedFile = fromFile self.associatedFileField.setText(self.associatedFile.getPath()) self.params = JSONObject() try: try: while (line = br.readLine()) != None: pdata.append(line) finally: br.close() self.params = JSONObject(pdata.__str__()) self.savedParams = self.params.__str__() self.setUIfromJSON() self.syncJSONtoUI() except Exception as e: e.printStackTrace() def saveParamsJSON(self, saveAs): """ generated source for method saveParamsJSON """ try: if saveAs or self.associatedFile == None: fc.setFileFilter(PlayerFilter()) if returnVal == JFileChooser.APPROVE_OPTION and fc.getSelectedFile() != None: if toFile.__name__.contains("."): self.associatedFile = File(toFile.getParentFile(), toFile.__name__.substring(0, toFile.__name__.lastIndexOf(".")) + ".player") else: self.associatedFile = File(toFile.getParentFile(), toFile.__name__ + ".player") self.associatedFileField.setText(self.associatedFile.getPath()) else: return bw.write(self.params.__str__()) bw.close() self.savedParams = self.params.__str__() self.syncJSONtoUI() except IOException as ie: ie.printStackTrace() def saveButtonMethod(self): """ generated source for method saveButtonMethod """ return AbstractAction("Save") def saveAsButtonMethod(self): """ generated source for method saveAsButtonMethod """ return AbstractAction("Save As") def loadButtonMethod(self): """ generated source for method loadButtonMethod """ return AbstractAction("Load") class PlayerFilter(FileFilter): """ generated source for class PlayerFilter """ def accept(self, f): """ generated source for method accept """ if f.isDirectory(): return True return f.__name__.endsWith(".player") def getDescription(self): """ generated source for method getDescription """ return "GGP Players (*.player)"
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, IContextMenuFactory, IExtensionStateListener): # # implement IBurpExtender # def registerExtenderCallbacks(self, callbacks): # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("Burp Scope Monitor Experimental") self.GLOBAL_HANDLER_ANALYZED = False self.GLOBAL_HANDLER = False self.STATUS = False self.AUTOSAVE_REQUESTS = 10 self.AUTOSAVE_TIMEOUT = 600 # 10 minutes should be fine self.CONFIG_INSCOPE = True self.BAD_EXTENSIONS_DEFAULT = [ '.gif', '.png', '.js', '.woff', '.woff2', '.jpeg', '.jpg', '.css', '.ico', '.m3u8', '.ts', '.svg' ] self.BAD_MIMES_DEFAULT = [ 'gif', 'script', 'jpeg', 'jpg', 'png', 'video', 'mp2t' ] self.BAD_EXTENSIONS = self.BAD_EXTENSIONS_DEFAULT self.BAD_MIMES = self.BAD_MIMES_DEFAULT # create the log and a lock on which to synchronize when adding log entries self._currentlyDisplayedItem = None self.SELECTED_MODEL_ROW = 0 self.SELECTED_VIEW_ROW = 0 self._log = ArrayList() self._fullLog = ArrayList() self._lock = Lock() self._lockFile = Lock() # main split pane self._parentPane = JTabbedPane() self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT) ##### config pane self._config = JTabbedPane() config = JPanel() iexport = JPanel() #config.setLayout(BorderLayout()) config.setLayout(None) iexport.setLayout(None) # config radio button X_BASE = 40 Y_OFFSET = 5 Y_OPTION = 200 Y_OPTION_SPACING = 20 Y_CHECKMARK_SPACING = 20 self.showAllButton = JRadioButton(SHOW_ALL_BUTTON_LABEL, True) self.showNewButton = JRadioButton(SHOW_NEW_BUTTON_LABEL, False) self.showTestedButton = JRadioButton(SHOW_TEST_BUTTON_LABEL, False) self.showAllButton.setBounds(40, 60 + Y_OFFSET, 400, 30) self.showNewButton.setBounds(40, 80 + Y_OFFSET, 400, 30) self.showTestedButton.setBounds(40, 100 + Y_OFFSET, 400, 30) #self.showNewButton = JRadioButton(SHOW_NEW_BUTTON_LABEL, False) #self.showTestedButton = JRadioButton(SHOW_TEST_BUTTON_LABEL, False) self.showAllButton.addActionListener(self.handleRadioConfig) self.showNewButton.addActionListener(self.handleRadioConfig) self.showTestedButton.addActionListener(self.handleRadioConfig) self.clearButton = JButton("Clear") self.clearButton.addActionListener(self.handleClearButton) self.clearButton.setBounds(40, 20, 100, 30) self.startButton = JButton(MONITOR_ON_LABEL) self.startButton.addActionListener(self.handleStartButton) self.startButton.setBounds(150, 20, 200, 30) self.badExtensionsLabel = JLabel("Ignore extensions:") self.badExtensionsLabel.setBounds(X_BASE, 150, 200, 30) self.badExtensionsText = JTextArea("") self.loadBadExtensions() self.badExtensionsText.setBounds(X_BASE, 175, 310, 30) self.badExtensionsButton = JButton("Save") self.badExtensionsButton.addActionListener( self.handleBadExtensionsButton) self.badExtensionsButton.setBounds(355, 175, 70, 30) self.badExtensionsDefaultButton = JButton("Load Defaults") self.badExtensionsDefaultButton.addActionListener( self.handleBadExtensionsDefaultButton) self.badExtensionsDefaultButton.setBounds(430, 175, 120, 30) self.badMimesLabel = JLabel("Ignore mime types:") self.badMimesLabel.setBounds(X_BASE, 220, 200, 30) self.badMimesText = JTextArea("") self.loadBadMimes() self.badMimesText.setBounds(X_BASE, 245, 310, 30) self.badMimesButton = JButton("Save") self.badMimesButton.addActionListener(self.handleBadMimesButton) self.badMimesButton.setBounds(355, 245, 70, 30) self.badMimesDefaultButton = JButton("Load Defaults") self.badMimesDefaultButton.addActionListener( self.handleBadMimesDefaultButton) self.badMimesDefaultButton.setBounds(430, 245, 120, 30) self.otherLabel = JLabel("Other:") self.otherLabel.setBounds(40, 300, 120, 30) self.otherLabel2 = JLabel("Other:") self.otherLabel2.setBounds(X_BASE, Y_OPTION, 120, 30) self.autoSaveOption = JCheckBox("Auto save periodically") self.autoSaveOption.setSelected(True) self.autoSaveOption.addActionListener(self.handleAutoSaveOption) self.autoSaveOption.setBounds(X_BASE, Y_OPTION + Y_CHECKMARK_SPACING, 420, 30) self.repeaterOptionButton = JCheckBox( "Repeater request automatically marks as analyzed") self.repeaterOptionButton.setSelected(True) self.repeaterOptionButton.addActionListener( self.handleRepeaterOptionButton) self.repeaterOptionButton.setBounds(50, 330, 420, 30) self.scopeOptionButton = JCheckBox("Follow Burp Target In Scope rules") self.scopeOptionButton.setSelected(True) self.scopeOptionButton.addActionListener(self.handleScopeOptionButton) self.scopeOptionButton.setBounds(50, 350, 420, 30) self.startOptionButton = JCheckBox("Autostart Scope Monitor") self.startOptionButton.setSelected(True) self.startOptionButton.addActionListener(self.handleStartOption) self.startOptionButton.setBounds(50, 350 + Y_OPTION_SPACING, 420, 30) self.markTestedRequestsProxy = JCheckBox( "Color request in Proxy tab if analyzed") self.markTestedRequestsProxy.setSelected(True) self.markTestedRequestsProxy.addActionListener( self.handleTestedRequestsProxy) self.markTestedRequestsProxy.setBounds(50, 350 + Y_OPTION_SPACING * 2, 420, 30) self.markNotTestedRequestsProxy = JCheckBox( "Color request in Proxy tab if NOT analyzed") self.markNotTestedRequestsProxy.setSelected(True) self.markNotTestedRequestsProxy.addActionListener( self.handleNotTestedRequestsProxy) self.markNotTestedRequestsProxy.setBounds(50, 350 + Y_OPTION_SPACING * 3, 420, 30) self.saveButton = JButton("Save now") self.saveButton.addActionListener(self.handleSaveButton) self.saveButton.setBounds(X_BASE + 320, 95, 90, 30) self.loadButton = JButton("Load now") self.loadButton.addActionListener(self.handleLoadButton) self.loadButton.setBounds(X_BASE + 420, 95, 90, 30) self.selectPath = JButton("Select path") self.selectPath.addActionListener(self.selectExportFile) self.selectPath.setBounds(X_BASE + 530, 60, 120, 30) self.selectPathText = JTextArea("") self.selectPathText.setBounds(X_BASE, 60, 510, 30) self.selectPathLabel = JLabel("State file:") self.selectPathLabel.setBounds(X_BASE, 30, 200, 30) bGroup = ButtonGroup() bGroup.add(self.showAllButton) bGroup.add(self.showNewButton) bGroup.add(self.showTestedButton) config.add(self.clearButton) config.add(self.startButton) config.add(self.startOptionButton) config.add(self.showAllButton) config.add(self.showNewButton) config.add(self.showTestedButton) config.add(self.badExtensionsButton) config.add(self.badExtensionsText) config.add(self.badExtensionsLabel) config.add(self.badMimesButton) config.add(self.badMimesText) config.add(self.badMimesLabel) config.add(self.badExtensionsDefaultButton) config.add(self.badMimesDefaultButton) config.add(self.otherLabel) config.add(self.repeaterOptionButton) config.add(self.scopeOptionButton) config.add(self.markTestedRequestsProxy) config.add(self.markNotTestedRequestsProxy) iexport.add(self.saveButton) iexport.add(self.loadButton) iexport.add(self.selectPath) iexport.add(self.selectPathText) iexport.add(self.selectPathLabel) iexport.add(self.otherLabel2) iexport.add(self.autoSaveOption) self._config.addTab("General", config) self._config.addTab("Import/Export", iexport) ##### end config pane self._parentPane.addTab("Monitor", self._splitpane) self._parentPane.addTab("Config", self._config) # table of log entries self.logTable = Table(self) #self.logTable.setDefaultRenderer(self.logTable.getColumnClass(0), ColoredTableCellRenderer(self)) self.logTable.setAutoCreateRowSorter(True) self.logTable.setRowSelectionAllowed(True) renderer = ColoredTableCellRenderer(self) #column = TableColumn(0, 190, renderer, None) print 'Initiating... ' # this could be improved by fetching initial dimensions self.logTable.getColumn("URL").setPreferredWidth(720) # noscope self.logTable.getColumn("URL").setResizable(True) self.logTable.getColumn("Checked").setCellRenderer(renderer) self.logTable.getColumn("Checked").setPreferredWidth(80) self.logTable.getColumn("Checked").setMaxWidth(80) self.logTable.getColumn("Method").setPreferredWidth(120) #self.logTable.getColumn("Method").setMaxWidth(120) self.logTable.getColumn("Method").setResizable(True) self.logTable.getColumn("Time").setPreferredWidth(120) # noscope self.logTable.getColumn("Time").setResizable(True) scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(scrollPane) # tabs with request/response viewers tabs = JTabbedPane() self._requestViewer = callbacks.createMessageEditor(self, False) self._responseViewer = callbacks.createMessageEditor(self, False) tabs.addTab("Request", self._requestViewer.getComponent()) tabs.addTab("Response", self._responseViewer.getComponent()) self._splitpane.setRightComponent(tabs) ## Row sorter shit #self._tableRowSorterAutoProxyAutoAction = CustomTableRowSorter(self.logTable.getModel()) #self.logTable.setRowSorter(self._tableRowSorterAutoProxyAutoAction) markAnalyzedButton = JMenuItem("Mark Requests as Analyzed") markAnalyzedButton.addActionListener(markRequestsHandler(self, True)) markNotAnalyzedButton = JMenuItem("Mark Requests as NOT Analyzed") markNotAnalyzedButton.addActionListener( markRequestsHandler(self, False)) sendRequestMenu = JMenuItem("Send Request to Repeater") sendRequestMenu.addActionListener(sendRequestRepeater(self)) deleteRequestMenu = JMenuItem("Delete request") deleteRequestMenu.addActionListener(deleteRequestHandler(self)) self.menu = JPopupMenu("Popup") self.menu.add(markAnalyzedButton) self.menu.add(markNotAnalyzedButton) self.menu.add(sendRequestMenu) self.menu.add(deleteRequestMenu) # customize our UI components callbacks.customizeUiComponent(self._parentPane) callbacks.customizeUiComponent(self._splitpane) callbacks.customizeUiComponent(self._config) callbacks.customizeUiComponent(config) callbacks.customizeUiComponent(self.logTable) callbacks.customizeUiComponent(scrollPane) callbacks.customizeUiComponent(tabs) callbacks.registerContextMenuFactory(self) callbacks.registerExtensionStateListener(self) callbacks.registerScannerCheck(passiveScanner(self)) # add the custom tab to Burp's UI callbacks.addSuiteTab(self) # register ourselves as an HTTP listener callbacks.registerHttpListener(self) self.loadConfigs() print "Loaded!" print "Experimental import state.. " self.importState("") self.SC = sched.scheduler(time.time, time.sleep) self.SCC = self.SC.enter(10, 1, self.autoSave, (self.SC, )) self.SC.run() return ##### CUSTOM CODE ##### def loadConfigs(self): if self._callbacks.loadExtensionSetting("CONFIG_AUTOSTART") == "False": self.startOptionButton.setSelected(False) self.startOrStop(None, False) else: self.startOptionButton.setSelected(True) self.startOrStop(None, True) if self._callbacks.loadExtensionSetting("exportFile") != "": self.selectPathText.setText( self._callbacks.loadExtensionSetting("exportFile")) if self._callbacks.loadExtensionSetting("CONFIG_REPEATER") == "True": self.repeaterOptionButton.setSelected(True) else: self.repeaterOptionButton.setSelected(False) if self._callbacks.loadExtensionSetting("CONFIG_INSCOPE") == "True": self.scopeOptionButton.setSelected(True) else: self.scopeOptionButton.setSelected(False) if self._callbacks.loadExtensionSetting("CONFIG_AUTOSAVE") == "True": self.autoSaveOption.setSelected(True) else: self.autoSaveOption.setSelected(False) if self._callbacks.loadExtensionSetting( "CONFIG_HIGHLIGHT_TESTED") == "True": self.markTestedRequestsProxy.setSelected(True) else: self.markTestedRequestsProxy.setSelected(False) if self._callbacks.loadExtensionSetting( "CONFIG_HIGHLIGHT_NOT_TESTED") == "True": self.markNotTestedRequestsProxy.setSelected(True) else: self.markNotTestedRequestsProxy.setSelected(False) return def selectExportFile(self, event): parentFrame = JFrame() fileChooser = JFileChooser() fileChooser.setDialogTitle("Specify file to save state") fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY) userSelection = fileChooser.showOpenDialog(parentFrame) if (userSelection == JFileChooser.APPROVE_OPTION): fileLoad = fileChooser.getSelectedFile() filename = fileLoad.getAbsolutePath() self.selectPathText.setText(filename) print 'Filename selected:' + filename self._callbacks.saveExtensionSetting("exportFile", filename) return def extensionUnloaded(self): print 'extension unloading.. ' print 'canceling scheduler.. ' map(self.SC.cancel, self.SC.queue) return def loadBadExtensions(self): bad = self._callbacks.loadExtensionSetting("badExtensions") if bad: self.badExtensionsText.setText(bad) # transform text to array bad = bad.replace(" ", "") self.BAD_EXTENSIONS = bad.split(",") else: print 'no bad extension saved, reverting' self.badExtensionsText.setText(", ".join(self.BAD_EXTENSIONS)) def loadBadMimes(self): bad = self._callbacks.loadExtensionSetting("badMimes") if bad: self.badMimesText.setText(bad) bad = bad.replace(" ", "") self.BAD_MIMES = bad.split(",") else: print 'no bad mimes saved, reverting' self.badMimesText.setText(", ".join(self.BAD_MIMES)) ## GLOBAL CONTEXT CODE ## def createMenuItems(self, invocation): responses = invocation.getSelectedMessages() if responses > 0: ret = LinkedList() analyzedMenuItem = JMenuItem("Mark as analyzed") notAnalyzedMenuItem = JMenuItem("Mark as NOT analyzed") for response in responses: analyzedMenuItem.addActionListener( handleMenuItems(self, response, "analyzed")) notAnalyzedMenuItem.addActionListener( handleMenuItems(self, response, "not")) ret.add(analyzedMenuItem) ret.add(notAnalyzedMenuItem) return ret def getEndpoint(self, requestResponse): url_ = str(self._helpers.analyzeRequest(requestResponse).getUrl()) o = urlparse(url_) url = o.scheme + "://" + o.netloc + o.path #print "Url3: " + url return url def getMethod(self, requestResponse): return self._helpers.analyzeRequest(requestResponse).getMethod() ##### CUSTOM CODE ##### def handleTestedRequestsProxy(self, event): self._callbacks.saveExtensionSetting( "CONFIG_HIGHLIGHT_TESTED", str(self.markTestedRequestsProxy.isSelected())) return def handleNotTestedRequestsProxy(self, event): self._callbacks.saveExtensionSetting( "CONFIG_HIGHLIGHT_NOT_TESTED", str(self.markNotTestedRequestsProxy.isSelected())) return def handleStartOption(self, event): self._callbacks.saveExtensionSetting( "CONFIG_AUTOSTART", str(self.startOptionButton.isSelected())) #print 'saving autostart: ' + str(self.startOptionButton.isSelected()) return def startOrStop(self, event, autoStart): if (self.startButton.getText() == MONITOR_OFF_LABEL) or autoStart: self.startButton.setText(MONITOR_ON_LABEL) self.startButton.setBackground(GREEN_COLOR) self.STATUS = True else: self.startButton.setText(MONITOR_OFF_LABEL) self.startButton.setBackground(RED_COLOR) self.STATUS = False def handleStartButton(self, event): self.startOrStop(event, False) def handleAutoSaveOption(self, event): self._callbacks.saveExtensionSetting( "CONFIG_AUTOSAVE", str(self.autoSaveOption.isSelected())) return def handleSaveButton(self, event): self.exportState("") def handleLoadButton(self, event): self.importState("") def handleRepeaterOptionButton(self, event): self._callbacks.saveExtensionSetting( "CONFIG_REPEATER", str(self.repeaterOptionButton.isSelected())) return def handleScopeOptionButton(self, event): self.CONFIG_INSCOPE = self.scopeOptionButton.isSelected() self._callbacks.saveExtensionSetting("CONFIG_INSCOPE", str(self.CONFIG_INSCOPE)) return def handleBadExtensionsButton(self, event): #print "before BAD array: " print self.BAD_EXTENSIONS extensions = self.badExtensionsText.getText() self._callbacks.saveExtensionSetting("badExtensions", extensions) print 'New extensions blocked: ' + extensions bad = extensions.replace(" ", "") self.BAD_EXTENSIONS = bad.split(",") #print "BAD array: " #print self.BAD_EXTENSIONS def handleBadExtensionsDefaultButton(self, event): self.BAD_EXTENSIONS = self.BAD_EXTENSIONS_DEFAULT self.badExtensionsText.setText(", ".join(self.BAD_EXTENSIONS)) self._callbacks.saveExtensionSetting("badExtensions", ", ".join(self.BAD_EXTENSIONS)) return def handleBadMimesDefaultButton(self, event): self.BAD_MIMES = self.BAD_MIMES_DEFAULT self.badMimesText.setText(", ".join(self.BAD_MIMES)) self._callbacks.saveExtensionSetting("badExtensions", ", ".join(self.BAD_MIMES)) return def handleBadMimesButton(self, event): mimes = self.badMimesText.getText() self._callbacks.saveExtensionSetting("badMimes", mimes) print 'New mimes blocked: ' + mimes bad = mimes.replace(" ", "") self.BAD_MIMES = bad.split(",") def handleClearButton(self, event): print 'Clearing table' self._lock.acquire() self._log = ArrayList() self._fullLog = ArrayList() self._lock.release() return def handleRadioConfig(self, event): #print ' radio button clicked ' #print event.getActionCommand() self._lock.acquire() if event.getActionCommand() == SHOW_ALL_BUTTON_LABEL: print "Showing all" self._log = self._fullLog elif event.getActionCommand() == SHOW_NEW_BUTTON_LABEL: print "Showing new scope only" tmpLog = ArrayList() for item in self._fullLog: if not (item._analyzed): tmpLog.add(item) self._log = tmpLog elif event.getActionCommand() == SHOW_TEST_BUTTON_LABEL: print "Showing tested scope only" tmpLog = ArrayList() for item in self._fullLog: if item._analyzed: tmpLog.add(item) self._log = tmpLog else: print "unrecognized radio label" self.fireTableDataChanged() #self._tableRowSorterAutoProxyAutoAction.toggleSortOrder(1) #self.toggleSortOrder(2) #self.logTable.toggleSortOrder(2) # refresh table? self._lock.release() # # implement ITab # def getTabCaption(self): return "Scope Monitor" def getUiComponent(self): return self._parentPane # # implement IHttpListener # def markAnalyzed(self, messageIsRequest, state): #print "markAnalyzed..." self._lock.acquire() url = self.getEndpoint(messageIsRequest) for item in self._log: if url == item._url: item._analyzed = state self._lock.release() return self._lock.release() return def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): # only process requests #print "processing httpMessage.." #print messageIsRequest print "processHttpMessage toolFlag: " + str(toolFlag) #print " -- " + str(self._callbacks.getToolName(toolFlag)) + " -- " if not (self.STATUS): return #print "global handler status: (true): " + str(self.GLOBAL_HANDLER) #print "(processHTTP) messageIsRequest" #print messageIsRequest isFromPassiveScan = False if toolFlag == 1234: print "1 processHttpMessage: processing passiveScan item" isFromPassiveScan = True if toolFlag != 1234: if messageIsRequest and not (self.GLOBAL_HANDLER): print "1.5 processHttpMessage droping message" return if self.scopeOptionButton.isSelected(): url = self._helpers.analyzeRequest(messageInfo).getUrl() if not self._callbacks.isInScope(url): #print 'Url not in scope, skipping.. ' return #print "still processing httpMessage.., request came from: " + self._callbacks.getToolName(toolFlag) if toolFlag == 1234: print "2 processHttpMessage: processing passiveScan item; setting toolFlag to proxy (4)" toolFlag = 4 #toolFlag = 4 if ((self._callbacks.getToolName(toolFlag) != "Repeater") and (self._callbacks.getToolName(toolFlag) != "Proxy") and (self._callbacks.getToolName(toolFlag) != "Target")): #print 'Aborting processHTTP, request came from: ' + str(self._callbacks.getToolName(toolFlag)) print "Droping request from " + str( self._callbacks.getToolName(toolFlag)) return #print "---> still processing from tool: " + str(self._callbacks.getToolName(toolFlag)) url = self.getEndpoint(messageInfo) method = self.getMethod(messageInfo) #print "(processHTTP) before extensions check: " + url for extension in self.BAD_EXTENSIONS: if url.endswith(extension): return if messageInfo.getResponse(): mime = self._helpers.analyzeResponse( messageInfo.getResponse()).getStatedMimeType() #print 'Declared mime:' + mime mime = mime.lower() if mime in self.BAD_MIMES: #print 'Bad mime:' + mime return #print "[httpMessage] before lock" # create a new log entry with the message details self._lock.acquire() row = self._log.size() for item in self._log: if url == item._url: if method == self._helpers.analyzeRequest( item._requestResponse).getMethod(): #print 'duplicate URL+method, skipping.. ' self._lock.release() # has it been analyzed? analyzed = False if self._callbacks.getToolName(toolFlag) == "Repeater": if self.repeaterOptionButton.isSelected(): analyzed = True #print "[httpMessage] setting analyzed as true" if self.GLOBAL_HANDLER_ANALYZED: analyzed = True item._analyzed = analyzed self.paintItems(messageInfo, item) return #print "[httpMessage] before setComment" if not (isFromPassiveScan): messageInfo.setComment(SCOPE_MONITOR_COMMENT) # reached here, must be new entry analyzed = False if self._callbacks.getToolName(toolFlag) == "Repeater": if self.repeaterOptionButton.isSelected(): analyzed = True #print "[httpMessage] setting analyzed as true" if self.GLOBAL_HANDLER_ANALYZED: analyzed = True #print "[httpMessage] after comment" #print 'in httpmessage, response:' #print self._helpers.analyzeResponse(messageInfo.getResponse()) date = datetime.datetime.fromtimestamp( time.time()).strftime('%H:%M:%S %d %b %Y') entry = LogEntry(toolFlag, self._callbacks.saveBuffersToTempFiles(messageInfo), url, analyzed, date, method) #print "toolFlag: " + str(toolFlag) #print "(processHTTP) Adding URL: " + url self._log.add(entry) self._fullLog.add(entry) self.fireTableRowsInserted(row, row) self.paintItems(messageInfo, entry) self._lock.release() #print "columnCoun:" + str(self.logTable.getColumnCount()) # # extend AbstractTableModel # def paintItems(self, messageInfo, item): ''' print "in paint Items" print "mark color is: (true)" + str(self.markTestedRequestsProxy.isSelected()) print "global handler analyzed: :" + str(self.GLOBAL_HANDLER_ANALYZED) print "item analyzed should be the same ^^:" + str(item._analyzed) ''' if (self.markTestedRequestsProxy.isSelected()) and ( item._analyzed and self.GLOBAL_HANDLER_ANALYZED): messageInfo.setHighlight("green") return if self.markNotTestedRequestsProxy.isSelected() and not ( item._analyzed): messageInfo.setHighlight("red") def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 4 def getColumnName(self, columnIndex): if columnIndex == 0: return "Checked" if columnIndex == 1: return "URL" if columnIndex == 2: return "Method" if columnIndex == 3: return "Time" def getValueAt(self, rowIndex, columnIndex): logEntry = self._log.get(rowIndex) #self.setBackground(Color.GREEN) return self.returnEntry(rowIndex, columnIndex, logEntry) if self.showNewButton.isSelected() and not (logEntry._analyzed): return self.returnEntry(rowIndex, columnIndex, logEntry) elif self.showTestedButton.isSelected() and logEntry._analyzed: return self.returnEntry(rowIndex, columnIndex, logEntry) elif self.showAllButton.isSelected(): return self.returnEntry(rowIndex, columnIndex, logEntry) def returnEntry(self, rowIndex, columnIndex, entry): logEntry = self._log.get(rowIndex) if columnIndex == 0: if logEntry._analyzed: return "True" else: return "False" if columnIndex == 1: return self._helpers.urlDecode(logEntry._url) if columnIndex == 2: return logEntry._method if columnIndex == 3: return logEntry._date # return date return "" # # implement IMessageEditorController # this allows our request/response viewers to obtain details about the messages being displayed # def getHttpService(self): return self._currentlyDisplayedItem.getHttpService() def getRequest(self): #print 'getRequest called' return self._currentlyDisplayedItem.getRequest() def getResponse(self): #print 'getResponse called: ' print self._currentlyDisplayedItem.getResponse() return self._currentlyDisplayedItem.getResponse() def exportRequest(self, entity, filename): line = str(entity._analyzed) + "," line = line + self._helpers.urlEncode(entity._url).replace( ",", "%2c") + "," # URL is encoded so we should be good line = line + entity._method + "," line = line + entity._date line = line + '\n' #print 'Exporting: "' + line + '"' return line def exportUrlEncode(self, url): return self._helpers.urlEncode(url).replace(",", "%2c") def exportState(self, filename): filename = self.selectPathText.getText() if filename == "": filename = self._callbacks.loadExtensionSetting("exportFile") print 'Empty filename, skipping export' return else: self._callbacks.saveExtensionSetting("exportFile", filename) print 'saving state to: ' + filename savedUrls = [] self._lockFile.acquire() try: with open(filename, 'r') as fr: savedEntries = fr.read().splitlines() savedUrls = [] for savedEntry in savedEntries: savedUrls.append(savedEntry.split(",")[1]) #print "savedUrls len: " + str(len(savedUrls)) #print "savedUrls:" #print savedUrls fr.close() except IOError: print "Autosaving skipped as file doesn't exist yet" with open(filename, 'a+') as f: for item in self._log: if self.exportUrlEncode(item._url) not in savedUrls: line = self.exportRequest(item, "xx") f.write(line) f.close() self._lockFile.release() return def importState(self, filename): filename = self.selectPathText.getText() if filename == "": filename = self._callbacks.loadExtensionSetting("exportFile") print 'Empty filename, skipping import' return else: self._callbacks.saveExtensionSetting("exportFile", filename) print 'loading state from: ' + filename self.STATUS = False self._lockFile.acquire() with open(filename, 'r') as f: proxy = self._callbacks.getProxyHistory() proxyItems = [] for item in proxy: if item.getComment(): if SCOPE_MONITOR_COMMENT in item.getComment(): proxyItems.append(item) print 'proxyItems has: ' + str(len(proxyItems)) # TODO - if no proxy items, sraight to import lines = f.read().splitlines() for line in lines: data = line.split(",") url = data[1] url = self._helpers.urlDecode(url) #print 'Saving: ' + url if not self._callbacks.isInScope(URL(url)): print '-- imported url not in scope, skipping.. ' continue analyzed = False if data[0] == "True": analyzed = True #print '.. simulating url search.. ' requestResponse = None for request in proxyItems: if url == self.getEndpoint(request): #print 'Match found when importing for url: ' + url requestResponse = request break self._log.add( LogEntry("", requestResponse, url, analyzed, data[3], data[2])) self._lockFile.release() print 'finished loading.. ' #print 'size: ' + str(self._log.size()) self.fireTableDataChanged() if self.startButton.getText() == MONITOR_ON_LABEL: self.STATUS = True return def autoSave(self, sc): #print 'autosaving.. lol what' if self.autoSaveOption.isSelected(): print "[" + self.getTime( ) + "] autosaving to " + self._callbacks.loadExtensionSetting( "exportFile") self.exportState("") self.SC.enter(self.AUTOSAVE_TIMEOUT, 1, self.autoSave, (self.SC, )) return def getTime(self): date = datetime.datetime.fromtimestamp( time.time()).strftime('%H:%M:%S') return date
class BurpExtender(IBurpExtender, IProxyListener, ITab): def getTabCaption(self): ### ITab return NAME def getUiComponent(self): ### ITab return self.settings def registerExtenderCallbacks(self, this_callbacks): ### IBurpExtender global callbacks, helpers global extension_enable global remove_csrf_headers, remove_csrf_params, change_method_to_post global change_ct_to_json, change_ct_to_plain, change_to_get callbacks = this_callbacks helpers = callbacks.getHelpers() callbacks.setExtensionName(NAME) self.settings = JPanel(GridBagLayout()) c = GridBagConstraints() self.extension_enable_box = JCheckBox('Enable extension', extension_enable) self.extension_enable_box.setFont(Font("Serif", Font.BOLD, 20)) self.extension_enable_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 0 c.gridwidth = 1 c.weightx = 1 c.fill = GridBagConstraints.NONE c.anchor = GridBagConstraints.WEST self.settings.add(self.extension_enable_box, c) self.remove_csrf_headers_box = JCheckBox('Remove CSRF headers', remove_csrf_params) self.remove_csrf_headers_box.setFont(Font("Serif", Font.BOLD, 20)) self.remove_csrf_headers_box.setForeground(Color(0, 0, 153)) c.insets = Insets(40, 5, 5, 5) c.gridx = 0 c.gridy = 1 self.settings.add(self.remove_csrf_headers_box, c) remove_csrf_headers_box_lbl = JLabel( 'Check to remove headers with CSRF tokens from all requests.') c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 2 self.settings.add(remove_csrf_headers_box_lbl, c) self.remove_csrf_params_box = JCheckBox('Remove CSRF parameters', remove_csrf_params) self.remove_csrf_params_box.setFont(Font("Serif", Font.BOLD, 20)) self.remove_csrf_params_box.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 3 self.settings.add(self.remove_csrf_params_box, c) remove_csrf_params_box_lbl = JLabel( 'Check to remove URL/body parameters with CSRF tokens from all requests. URL-encoded, multipart, JSON parameters are supported.' ) c.gridx = 0 c.gridy = 4 self.settings.add(remove_csrf_params_box_lbl, c) self.change_method_to_post_box = JCheckBox( 'Change HTTP method to POST', change_method_to_post) self.change_method_to_post_box.setFont(Font("Serif", Font.BOLD, 20)) self.change_method_to_post_box.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 5 self.settings.add(self.change_method_to_post_box, c) change_method_to_post_lbl = JLabel( 'Check to convert PUT/DELETE/PATCH method to POST in all requests.' ) c.gridx = 0 c.gridy = 6 self.settings.add(change_method_to_post_lbl, c) self.change_ct_to_json_box = JCheckBox('Change media type to json', change_ct_to_json) self.change_ct_to_json_box.setFont(Font("Serif", Font.BOLD, 20)) self.change_ct_to_json_box.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 7 self.settings.add(self.change_ct_to_json_box, c) change_ct_to_json_lbl = JLabel( 'Check to convert body to json and set Content-Type to application/json in url-encoded requests.' ) c.gridx = 0 c.gridy = 8 self.settings.add(change_ct_to_json_lbl, c) self.change_ct_to_plain_box = JCheckBox( 'Change Content-Type to text/plain', change_ct_to_plain) self.change_ct_to_plain_box.setFont(Font("Serif", Font.BOLD, 20)) self.change_ct_to_plain_box.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 9 self.settings.add(self.change_ct_to_plain_box, c) change_ct_to_plain_lbl = JLabel( 'Check to set Content-Type to text/plain in request with non-simple media type. Simple media types - application/application/x-www-form-urlencoded, text/plain, multipart/form-data.' ) c.gridx = 0 c.gridy = 10 self.settings.add(change_ct_to_plain_lbl, c) self.change_to_get_box = JCheckBox('Change to GET', change_to_get) self.change_to_get_box.setFont(Font("Serif", Font.BOLD, 20)) self.change_to_get_box.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 11 self.settings.add(self.change_to_get_box, c) change_to_get_lbl = JLabel( 'Check to convert POST/PUT/DELETE/PATCH url-encoded requests to GET.' ) c.gridx = 0 c.gridy = 12 self.settings.add(change_to_get_lbl, c) callbacks.customizeUiComponent(self.settings) callbacks.addSuiteTab(self) callbacks.registerProxyListener(self) print "Successfully loaded %s v%s" % (NAME, VERSION) def processProxyMessage(self, messageIsRequest, message): ### IProxyListener extension_enable = self.extension_enable_box.isSelected() if not extension_enable: return # Do nothing remove_csrf_headers = self.remove_csrf_headers_box.isSelected() remove_csrf_params = self.remove_csrf_params_box.isSelected() change_method_to_post = self.change_method_to_post_box.isSelected() change_ct_to_json = self.change_ct_to_json_box.isSelected() change_ct_to_plain = self.change_ct_to_plain_box.isSelected() change_to_get = self.change_to_get_box.isSelected() request_response = message.getMessageInfo() request_info = helpers.analyzeRequest(request_response) request_method = request_info.getMethod() if not messageIsRequest or request_method not in [ 'POST', 'PUT', 'DELETE', 'PATCH' ]: return # Do nothing http_service = request_response.getHttpService() request = request_response.getRequest() headers = request_info.getHeaders() parameters = request_info.getParameters() new_headers = headers if remove_csrf_headers: new_headers = filter_headers(headers) # Remove CSRF headers if change_ct_to_plain and request_info.getContentType() not in [ IRequestInfo.CONTENT_TYPE_URL_ENCODED, IRequestInfo.CONTENT_TYPE_MULTIPART ]: for i in range(len(new_headers)): if new_headers[i].lower().startswith( 'content-type'): # Change CT to text/plain new_headers[i] = 'Content-Type: text/plain' if remove_csrf_params: for parameter in parameters: # Remove CSRF parameters from request's body or URL for csrf_param in csrf_params_names: if parameter.getType() != IParameter.PARAM_COOKIE and \ csrf_param.lower() in parameter.getName().lower(): if request_info.getContentType( ) == IRequestInfo.CONTENT_TYPE_MULTIPART: start = parameter.getNameStart() end = parameter.getNameEnd() request = request[:start] + helpers.stringToBytes( "REPLACEMENT") + request[end:] elif parameter.getType() == IParameter.PARAM_JSON: start = parameter.getNameStart() - 1 end = parameter.getValueEnd() + 1 request = request[:start] + request[end:] offset = helpers.analyzeRequest( http_service, request).getBodyOffset() body = request[offset:] body = re.sub(",\s*,", ",", body) body = re.sub("{\s*,", "{", body) body = re.sub(",\s*}", "}", body) request = helpers.buildHttpMessage(headers, body) elif parameter.getType() in [ IParameter.PARAM_URL, IParameter.PARAM_BODY ]: request = helpers.removeParameter( request, parameter) offset = helpers.analyzeRequest(http_service, request).getBodyOffset() body = request[offset:] if change_ct_to_json and request_info.getContentType( ) == IRequestInfo.CONTENT_TYPE_URL_ENCODED: for i in range(len(new_headers)): if new_headers[i].lower().startswith( 'content-type'): # Change to JSON from URL-encoded new_headers[i] = 'Content-Type: application/json' body = safe_bytes_to_string(body) d = dict((k, v if len(v) > 1 else v[0]) for k, v in parse_qs(body).iteritems()) body = dumps(d) if change_method_to_post or (change_to_get and not change_ct_to_json and \ request_info.getContentType() == IRequestInfo.CONTENT_TYPE_URL_ENCODED): for i in range(len(new_headers)): if new_headers[i].startswith("PUT") or new_headers[i].startswith("DELETE") \ or new_headers[i].startswith("PATCH"): new_headers[i] = new_headers[i].replace( request_method, 'POST', 1) break new_request = helpers.buildHttpMessage( new_headers, body) # Create new request with valid Content-Length if change_to_get and not change_ct_to_json and request_info.getContentType( ) == IRequestInfo.CONTENT_TYPE_URL_ENCODED: new_request = helpers.toggleRequestMethod( new_request) # Change any URL-encoded request to GET message.setInterceptAction( IInterceptedProxyMessage.ACTION_FOLLOW_RULES_AND_REHOOK) message.getMessageInfo().setRequest(new_request) message.getMessageInfo().setHighlight('red')
class MPConfig(TreeSelectionListener): """The MPConfig component initializes the KConfig library with the requested configuration, and buildst the GUI, consisting of a "Load" and a "Save as" buttons, a search field, "show all" checkbox, tree view and information text view.""" def __init__(self, kconfig_file="Kconfig", config_file=".config", systemLogger=None): """[summary] Parameters ---------- kconfig_file : string (default: "Kconfig") The Kconfig configuration file config_file : string (default: ".config") The save file which will be used for loading and saving the settings systemLogger (default: None) A system logger object. If None then print statements are used for logging. """ global log if systemLogger: log = systemLogger # Load Kconfig configuration files self.kconfig = Kconfig(kconfig_file) setKConfig(self.kconfig) if os.path.isfile(config_file): log.info(self.kconfig.load_config(config_file)) elif os.path.isfile(".config"): log.info(self.kconfig.load_config(".config")) self.tree = KConfigTree(self.kconfig) self.tree.addTreeSelectionListener(self.treeSelectionChanged) jTreeSP = JScrollPane(self.tree) self.jta = JTextArea() self.jta.setEditable(False) jTextSP = JScrollPane(self.jta) toolPanel = JPanel() toolPanel.setLayout(BoxLayout(toolPanel, BoxLayout.X_AXIS)) toolPanel.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0)) toolPanel.add(JLabel("Search: ")) jSearchPanel = JPanel() jSearchPanel.setLayout(BoxLayout(jSearchPanel, BoxLayout.X_AXIS)) self.jSearchField = JTextField() jSearchPanel.setBackground(self.jSearchField.getBackground()) jSearchPanel.setBorder(self.jSearchField.getBorder()) self.jSearchField.setBorder(None) self.jSearchField.getDocument().addDocumentListener( SearchListener(self.tree)) jSearchPanel.add(self.jSearchField) clearSearchButton = JButton(u'\u00d7', actionPerformed=self.clearSearch) d = clearSearchButton.getPreferredSize() clearSearchButton.setPreferredSize(Dimension(d.height, d.height)) clearSearchButton.setBackground(self.jSearchField.getBackground()) clearSearchButton.setBorder(None) clearSearchButton.setOpaque(False) clearSearchButton.setContentAreaFilled(False) clearSearchButton.setFocusPainted(False) jSearchPanel.add(clearSearchButton) toolPanel.add(jSearchPanel) self.showAllCheckBox = JCheckBox("Show all", actionPerformed=self.OnShowAllCheck) toolPanel.add(self.showAllCheckBox) splitPane = JSplitPane(JSplitPane.VERTICAL_SPLIT, jTreeSP, jTextSP) splitPane.setOneTouchExpandable(True) splitPane.setDividerLocation(300) treePanel = JPanel(BorderLayout()) treePanel.add(toolPanel, BorderLayout.NORTH) treePanel.add(splitPane, BorderLayout.CENTER) loadSavePanel = JPanel() loadSavePanel.setLayout(BoxLayout(loadSavePanel, BoxLayout.X_AXIS)) loadSavePanel.add( JButton("Load", actionPerformed=self.loadConfigDialog)) loadSavePanel.add( JButton("Save as", actionPerformed=self.writeConfigDialog)) self.rootPanel = JPanel() self.rootPanel.setLayout(BorderLayout()) self.rootPanel.add(loadSavePanel, BorderLayout.PAGE_START) self.rootPanel.add(treePanel, BorderLayout.CENTER) def clearSearch(self, event): self.jSearchField.setText("") def OnShowAllCheck(self, event): self.tree.setShowAll(self.showAllCheckBox.isSelected()) self.tree.doSearch(self.jSearchField.getText() ) # Must repeat the search if one is active def treeSelectionChanged(self, event): """When the user selects a new node in the tree, show info about the selected node in the info text area below the tree.""" path = event.getNewLeadSelectionPath() if path: comp = path.getLastPathComponent() if isinstance(comp, DefaultMutableTreeNode): nodeData = comp.getUserObject() if isinstance(nodeData, TreeNodeData): self.jta.setText(getNodeInfoString(nodeData.knode)) self.jta.setCaretPosition(0) def getPane(self): """Return the panel containing all the other components that is set up in __init__().""" return self.rootPanel def writeConfig(self, fileName): """Write the current configuration to the file specified.""" self.kconfig.write_config(fileName) # Save full configuration #self.kconfig.write_min_config(fileName) # Save minimal configuration def loadConfig(self, fileName): """Load configuration settings from the file specified.""" if os.path.isfile(fileName): log.info(self.kconfig.load_config(fileName)) self.tree.createKconfShadowModel(self.kconfig) self.tree.updateTree() def writeConfigDialog(self, e): """Open a file dialog to save configuration""" fileChooser = JFileChooser(os.getcwd()) retval = fileChooser.showSaveDialog(None) if retval == JFileChooser.APPROVE_OPTION: f = fileChooser.getSelectedFile() self.writeConfig(f.getPath()) def loadConfigDialog(self, e): """Open a file dialog to select configuration to load""" fileChooser = JFileChooser(os.getcwd()) retval = fileChooser.showOpenDialog(None) if retval == JFileChooser.APPROVE_OPTION: f = fileChooser.getSelectedFile() log.info("Selected file: " + f.getPath()) self.loadConfig(f.getPath())
class BurpExtender(IBurpExtender, IProxyListener, ITab): def getTabCaption(self): ### ITab return NAME def getUiComponent(self): ### ITab return self.tabs def setFontItalic(self, label): label.setFont( Font(label.getFont().getName(), Font.ITALIC, label.getFont().getSize())) def setFontBold(self, label): label.setFont(Font('Serif', Font.BOLD, label.getFont().getSize())) def registerExtenderCallbacks(self, this_callbacks): ### IBurpExtender global callbacks, helpers global extension_enable, in_scope_only global remove_csrf_headers, remove_csrf_params, change_method_to_post global change_ct_to_json, change_ct_to_plain, change_to_get callbacks = this_callbacks helpers = callbacks.getHelpers() callbacks.setExtensionName(NAME) self.settings = JPanel(GridBagLayout()) c = GridBagConstraints() self.extension_enable_box = JCheckBox('Enable extension', extension_enable) self.setFontBold(self.extension_enable_box) self.extension_enable_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 0 c.gridwidth = 1 c.weightx = 1 c.fill = GridBagConstraints.NONE c.anchor = GridBagConstraints.WEST self.settings.add(self.extension_enable_box, c) self.in_scope_only_box = JCheckBox('Modify only in-scope requests', in_scope_only) self.setFontBold(self.in_scope_only_box) self.in_scope_only_box.setForeground(Color(0, 0, 153)) c.insets = Insets(40, 5, 5, 5) c.gridx = 0 c.gridy = 1 self.settings.add(self.in_scope_only_box, c) self.remove_csrf_headers_box = JCheckBox('Remove CSRF headers', remove_csrf_params) self.setFontBold(self.remove_csrf_headers_box) self.remove_csrf_headers_box.setForeground(Color(0, 0, 153)) c.insets = Insets(40, 5, 5, 5) c.gridx = 0 c.gridy = 2 self.settings.add(self.remove_csrf_headers_box, c) remove_csrf_headers_box_lbl = JLabel( 'Check to remove headers with CSRF tokens from all requests.') self.setFontItalic(remove_csrf_headers_box_lbl) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 3 self.settings.add(remove_csrf_headers_box_lbl, c) self.remove_csrf_params_box = JCheckBox('Remove CSRF parameters', remove_csrf_params) self.setFontBold(self.remove_csrf_params_box) self.remove_csrf_params_box.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 4 self.settings.add(self.remove_csrf_params_box, c) remove_csrf_params_box_lbl = JLabel( 'Check to remove URL/body parameters with CSRF tokens from all requests. URL-encoded, multipart, JSON parameters are supported.' ) self.setFontItalic(remove_csrf_params_box_lbl) c.gridx = 0 c.gridy = 5 self.settings.add(remove_csrf_params_box_lbl, c) self.change_method_to_post_box = JCheckBox( 'Change HTTP method to POST', change_method_to_post) self.setFontBold(self.change_method_to_post_box) self.change_method_to_post_box.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 6 self.settings.add(self.change_method_to_post_box, c) change_method_to_post_lbl = JLabel( 'Check to convert PUT/DELETE/PATCH method to POST in all requests.' ) self.setFontItalic(change_method_to_post_lbl) c.gridx = 0 c.gridy = 7 self.settings.add(change_method_to_post_lbl, c) self.change_ct_to_json_box = JCheckBox('Change media type to json', change_ct_to_json) self.setFontBold(self.change_ct_to_json_box) self.change_ct_to_json_box.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 8 self.settings.add(self.change_ct_to_json_box, c) change_ct_to_json_lbl = JLabel( 'Check to convert body to json and set Content-Type to application/json in url-encoded requests.' ) self.setFontItalic(change_ct_to_json_lbl) c.gridx = 0 c.gridy = 9 self.settings.add(change_ct_to_json_lbl, c) self.change_ct_to_plain_box = JCheckBox( 'Change Content-Type to text/plain', change_ct_to_plain) self.setFontBold(self.change_ct_to_plain_box) self.change_ct_to_plain_box.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 10 self.settings.add(self.change_ct_to_plain_box, c) change_ct_to_plain_lbl = JLabel( 'Check to set Content-Type to text/plain in request with non-simple media type. Simple media types - application/application/x-www-form-urlencoded, text/plain, multipart/form-data.' ) self.setFontItalic(change_ct_to_plain_lbl) c.gridx = 0 c.gridy = 11 self.settings.add(change_ct_to_plain_lbl, c) self.change_to_get_box = JCheckBox('Change to GET', change_to_get) self.setFontBold(self.change_to_get_box) self.change_to_get_box.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 12 self.settings.add(self.change_to_get_box, c) change_to_get_lbl = JLabel( 'Check to convert POST/PUT/DELETE/PATCH url-encoded requests to GET.' ) self.setFontItalic(change_to_get_lbl) c.gridx = 0 c.gridy = 13 self.settings.add(change_to_get_lbl, c) self.csrf_headers_params = JPanel(GridBagLayout()) c = GridBagConstraints() lblParams = JLabel("CSRF parameters:") self.setFontBold(lblParams) lblParams.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 0 c.insets = Insets(5, 5, 5, 5) c.fill = GridBagConstraints.NONE c.anchor = GridBagConstraints.FIRST_LINE_END self.csrf_headers_params.add(lblParams, c) self.csrf_param_text_field = JTextField() c.fill = GridBagConstraints.BOTH c.gridx = 1 c.gridy = 0 self.csrf_headers_params.add(self.csrf_param_text_field, c) lblParamsNote = JLabel( "Remove parameter from request if name contains") self.setFontItalic(lblParamsNote) c.fill = GridBagConstraints.NONE c.gridx = 0 c.gridy = 1 self.csrf_headers_params.add(lblParamsNote, c) self.csrf_params_text_area = JTextArea() self.csrf_params_text_area.setColumns(20) self.csrf_params_text_area.setRows(10) self.csrf_params_text_area.setEditable(False) c.fill = GridBagConstraints.BOTH self.csrf_params_mouse_listener = TextAreaMouseListener( self.csrf_params_text_area) self.csrf_params_text_area.addMouseListener( self.csrf_params_mouse_listener) for name in csrf_params_names: self.csrf_params_text_area.append(name + os.linesep) c.gridx = 1 c.gridy = 1 sp = JScrollPane(self.csrf_params_text_area) self.csrf_headers_params.add(sp, c) buttonsPanel = JPanel(GridBagLayout()) _c = GridBagConstraints() _c.insets = Insets(3, 3, 3, 3) _c.gridx = 0 _c.gridy = 0 _c.fill = GridBagConstraints.BOTH _c.weightx = 1 _c.gridwidth = 1 handlers = ButtonHandlers(self.csrf_param_text_field, self.csrf_params_text_area, self.csrf_params_mouse_listener, csrf_params_names) self.csrf_param_add_button = JButton( 'Add', actionPerformed=handlers.handler_add) self.csrf_param_rm_button = JButton( 'Remove', actionPerformed=handlers.handler_rm) self.csrf_param_restore_button = JButton( 'Restore', actionPerformed=handlers.handler_restore) buttonsPanel.add(self.csrf_param_add_button, _c) _c.gridy = 1 buttonsPanel.add(self.csrf_param_rm_button, _c) _c.gridy = 2 buttonsPanel.add(self.csrf_param_restore_button, _c) _c.gridy = 3 c.gridx = 2 c.gridy = 1 c.fill = GridBagConstraints.NONE self.csrf_headers_params.add(buttonsPanel, c) lblHeaders = JLabel("CSRF headers:") self.setFontBold(lblHeaders) lblHeaders.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 2 c.insets = Insets(40, 5, 5, 5) c.fill = GridBagConstraints.NONE c.anchor = GridBagConstraints.FIRST_LINE_END self.csrf_headers_params.add(lblHeaders, c) self.csrf_header_text_field = JTextField() c.fill = GridBagConstraints.BOTH c.gridx = 1 c.gridy = 2 self.csrf_headers_params.add(self.csrf_header_text_field, c) lblHeadersNote = JLabel("Remove header from request if name equals to") self.setFontItalic(lblHeadersNote) c.fill = GridBagConstraints.NONE c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 3 self.csrf_headers_params.add(lblHeadersNote, c) self.csrf_headers_text_area = JTextArea() self.csrf_headers_text_area.setColumns(20) self.csrf_headers_text_area.setRows(10) self.csrf_headers_text_area.setEditable(False) c.fill = GridBagConstraints.BOTH self.csrf_headers_mouse_listener = TextAreaMouseListener( self.csrf_headers_text_area) self.csrf_headers_text_area.addMouseListener( self.csrf_headers_mouse_listener) for name in csrf_headers_names: self.csrf_headers_text_area.append(name + os.linesep) c.gridx = 1 c.gridy = 3 sp = JScrollPane(self.csrf_headers_text_area) self.csrf_headers_params.add(sp, c) buttonsPanel = JPanel(GridBagLayout()) _c = GridBagConstraints() _c.insets = Insets(3, 3, 3, 3) _c.gridx = 0 _c.gridy = 0 _c.fill = GridBagConstraints.BOTH _c.weightx = 1 _c.gridwidth = 1 handlers = ButtonHandlers(self.csrf_header_text_field, self.csrf_headers_text_area, self.csrf_headers_mouse_listener, csrf_headers_names) self.csrf_header_add_button = JButton( 'Add', actionPerformed=handlers.handler_add) self.csrf_header_rm_button = JButton( 'Remove', actionPerformed=handlers.handler_rm) self.csrf_header_restore_button = JButton( 'Restore', actionPerformed=handlers.handler_restore) buttonsPanel.add(self.csrf_header_add_button, _c) _c.gridy = 1 buttonsPanel.add(self.csrf_header_rm_button, _c) _c.gridy = 2 buttonsPanel.add(self.csrf_header_restore_button, _c) _c.gridy = 3 c.gridx = 2 c.gridy = 3 c.fill = GridBagConstraints.NONE self.csrf_headers_params.add(buttonsPanel, c) self.whitelist = JPanel(GridBagLayout()) c = GridBagConstraints() lblWhitelist = JLabel("URLs whitelist:") self.setFontBold(lblWhitelist) lblWhitelist.setForeground(Color(0, 0, 153)) c.gridx = 0 c.gridy = 0 c.insets = Insets(5, 5, 5, 5) c.fill = GridBagConstraints.NONE c.anchor = GridBagConstraints.FIRST_LINE_END self.whitelist.add(lblWhitelist, c) self.whitelist_text_field = JTextField() c.fill = GridBagConstraints.BOTH c.gridx = 1 c.gridy = 0 self.whitelist.add(self.whitelist_text_field, c) lblWhitelistNote = JLabel( "Do not perform request modification if URL starts with") self.setFontItalic(lblWhitelistNote) c.fill = GridBagConstraints.NONE c.gridx = 0 c.gridy = 1 self.whitelist.add(lblWhitelistNote, c) self.whitelist_text_area = JTextArea() self.whitelist_text_area.setColumns(30) self.whitelist_text_area.setRows(10) self.whitelist_text_area.setEditable(False) c.fill = GridBagConstraints.BOTH self.whitelist_mouse_listener = TextAreaMouseListener( self.whitelist_text_area) self.whitelist_text_area.addMouseListener( self.whitelist_mouse_listener) c.gridx = 1 c.gridy = 1 sp = JScrollPane(self.whitelist_text_area) self.whitelist.add(sp, c) buttonsPanel = JPanel(GridBagLayout()) _c = GridBagConstraints() _c.insets = Insets(3, 3, 3, 3) _c.gridx = 0 _c.gridy = 0 _c.fill = GridBagConstraints.BOTH _c.weightx = 1 _c.gridwidth = 1 handlers = ButtonHandlers(self.whitelist_text_field, self.whitelist_text_area, self.whitelist_mouse_listener, []) self.whitelist_add_button = JButton( 'Add', actionPerformed=handlers.handler_add) self.whitelist_rm_button = JButton('Remove', actionPerformed=handlers.handler_rm) self.whitelist_clear_button = JButton( 'Clear', actionPerformed=handlers.handler_restore) buttonsPanel.add(self.whitelist_add_button, _c) _c.gridy = 1 buttonsPanel.add(self.whitelist_rm_button, _c) _c.gridy = 2 buttonsPanel.add(self.whitelist_clear_button, _c) _c.gridy = 3 c.gridx = 2 c.gridy = 1 c.fill = GridBagConstraints.NONE self.whitelist.add(buttonsPanel, c) self.tabs = JTabbedPane() self.tabs.addTab('Settings', self.settings) self.tabs.addTab('CSRF params/headers to remove', self.csrf_headers_params) self.tabs.addTab('Requests whitelist', self.whitelist) callbacks.customizeUiComponent(self.tabs) callbacks.addSuiteTab(self) callbacks.registerProxyListener(self) callbacks.registerContextMenuFactory( SendToWhitelist(self.whitelist_text_area)) print "Successfully loaded %s v%s by Mikhail Egorov @0ang3el" % ( NAME, VERSION) def text_area_to_list(self, text_area): l = text_area.getText().strip().split('\n') return l if l != [''] else [] def filter_headers(self, headers): _headers = headers[:] for header in headers: for csrf_header in self.text_area_to_list( self.csrf_headers_text_area): if header.lower().startswith(csrf_header.lower()): _headers.remove(header) return _headers def processProxyMessage(self, messageIsRequest, message): ### IProxyListener global callbacks extension_enable = self.extension_enable_box.isSelected() if not extension_enable: return # Do nothing in_scope_only = self.in_scope_only_box.isSelected() remove_csrf_headers = self.remove_csrf_headers_box.isSelected() remove_csrf_params = self.remove_csrf_params_box.isSelected() change_method_to_post = self.change_method_to_post_box.isSelected() change_ct_to_json = self.change_ct_to_json_box.isSelected() change_ct_to_plain = self.change_ct_to_plain_box.isSelected() change_to_get = self.change_to_get_box.isSelected() request_response = message.getMessageInfo() request_info = helpers.analyzeRequest(request_response) request_method = request_info.getMethod() if in_scope_only and not callbacks.isInScope(request_info.getUrl()): return # Do nothing when URL is not in scope if not messageIsRequest or request_method not in [ 'POST', 'PUT', 'DELETE', 'PATCH' ]: return # Do nothing for whitelisted in self.text_area_to_list(self.whitelist_text_area): if str(request_info.getUrl()).startswith(whitelisted): return # Do nothing when URL is whitelisted http_service = request_response.getHttpService() request = request_response.getRequest() headers = request_info.getHeaders() parameters = request_info.getParameters() new_headers = headers if remove_csrf_headers: new_headers = self.filter_headers(headers) # Remove CSRF headers if change_ct_to_plain and request_info.getContentType() not in [ IRequestInfo.CONTENT_TYPE_URL_ENCODED, IRequestInfo.CONTENT_TYPE_MULTIPART ]: for i in range(len(new_headers)): if new_headers[i].lower().startswith( 'content-type'): # Change CT to text/plain new_headers[i] = 'Content-Type: text/plain' if remove_csrf_params: for parameter in parameters: # Remove CSRF parameters from request's body or URL for csrf_param in self.text_area_to_list( self.csrf_params_text_area): if parameter.getType() != IParameter.PARAM_COOKIE and \ csrf_param.lower() in parameter.getName().lower(): if request_info.getContentType( ) == IRequestInfo.CONTENT_TYPE_MULTIPART: start = parameter.getNameStart() end = parameter.getNameEnd() request = request[:start] + helpers.stringToBytes( "REPLACEMENT") + request[end:] elif parameter.getType() == IParameter.PARAM_JSON: start = parameter.getNameStart() - 1 end = parameter.getValueEnd() + 1 request = request[:start] + request[end:] offset = helpers.analyzeRequest( http_service, request).getBodyOffset() body = request[offset:] body = re.sub(",\s*,", ",", body) body = re.sub("{\s*,", "{", body) body = re.sub(",\s*}", "}", body) request = helpers.buildHttpMessage(headers, body) elif parameter.getType() in [ IParameter.PARAM_URL, IParameter.PARAM_BODY ]: request = helpers.removeParameter( request, parameter) offset = helpers.analyzeRequest(http_service, request).getBodyOffset() body = request[offset:] if change_ct_to_json and request_info.getContentType( ) == IRequestInfo.CONTENT_TYPE_URL_ENCODED: for i in range(len(new_headers)): if new_headers[i].lower().startswith( 'content-type'): # Change to JSON from URL-encoded new_headers[i] = 'Content-Type: application/json' body = safe_bytes_to_string(body) d = dict((k, v if len(v) > 1 else v[0]) for k, v in parse_qs(body).iteritems()) body = dumps(d) if (change_method_to_post and request_method != 'POST') or (change_to_get and not change_ct_to_json and \ request_info.getContentType() == IRequestInfo.CONTENT_TYPE_URL_ENCODED): for i in range(len(new_headers)): if new_headers[i].startswith("PUT") or new_headers[i].startswith("DELETE") \ or new_headers[i].startswith("PATCH"): new_headers[i] = new_headers[i].replace( request_method, 'POST', 1) break new_request = helpers.buildHttpMessage( new_headers, body) # Create new request with valid Content-Length if (change_method_to_post and request_method != 'POST') or (change_to_get and not change_ct_to_json and \ request_info.getContentType() == IRequestInfo.CONTENT_TYPE_URL_ENCODED): param1 = helpers.buildParameter('method', request_method, IParameter.PARAM_URL) param2 = helpers.buildParameter('_method', request_method, IParameter.PARAM_URL) new_request = helpers.addParameter(new_request, param1) new_request = helpers.addParameter(new_request, param2) if change_to_get: new_request = helpers.toggleRequestMethod( new_request) # Change any URL-encoded request to GET message.setInterceptAction( IInterceptedProxyMessage.ACTION_FOLLOW_RULES_AND_REHOOK) message.getMessageInfo().setRequest(new_request) message.getMessageInfo().setHighlight('red')
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, IContextMenuFactory): def registerExtenderCallbacks(self, callbacks): # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("Autorize") # create the log and a lock on which to synchronize when adding log entries self._log = ArrayList() self._lock = Lock() self._enfocementStatuses = ["Authorization bypass!","Authorization enforced??? (please configure enforcement detector)","Authorization enforced!"] self.intercept = 0 self.initInterceptionFilters() self.initEnforcementDetector() self.initEnforcementDetectorUnauthorized() self.initExport() self.initConfigurationTab() self.initTabs() self.initCallbacks() self.currentRequestNumber = 1 print "Thank you for installing Autorize v0.12 extension" print "Created by Barak Tawily" print "Contributors: Barak Tawily, Federico Dotta" print "\nGithub:\nhttps://github.com/Quitten/Autorize" return def initExport(self): # ## init enforcement detector tab # exportLType = JLabel("File Type:") exportLType.setBounds(10, 10, 100, 30) exportLES = JLabel("Enforcement Statuses:") exportLES.setBounds(10, 50, 160, 30) exportFileTypes = ["HTML","CSV"] self.exportType = JComboBox(exportFileTypes) self.exportType.setBounds(100, 10, 200, 30) exportES = ["All Statuses", self._enfocementStatuses[0], self._enfocementStatuses[1], self._enfocementStatuses[2]] self.exportES = JComboBox(exportES) self.exportES.setBounds(100, 50, 200, 30) exportLES = JLabel("Statuses:") exportLES.setBounds(10, 50, 100, 30) self.exportButton = JButton("Export",actionPerformed=self.export) self.exportButton.setBounds(390, 25, 100, 30) self.exportPnl = JPanel() self.exportPnl.setLayout(None); self.exportPnl.setBounds(0, 0, 1000, 1000); self.exportPnl.add(exportLType) self.exportPnl.add(self.exportType) self.exportPnl.add(exportLES) self.exportPnl.add(self.exportES) self.exportPnl.add(self.exportButton) def initEnforcementDetector(self): # ## init enforcement detector tab # # These two variable appears to be unused... self.EDFP = ArrayList() self.EDCT = ArrayList() EDLType = JLabel("Type:") EDLType.setBounds(10, 10, 140, 30) EDLContent = JLabel("Content:") EDLContent.setBounds(10, 50, 140, 30) EDLabelList = JLabel("Filter List:") EDLabelList.setBounds(10, 165, 140, 30) EDStrings = ["Headers (simple string): (enforced message headers contains)", "Headers (regex): (enforced messege headers contains)", "Body (simple string): (enforced messege body contains)", "Body (regex): (enforced messege body contains)", "Full request (simple string): (enforced messege contains)", "Full request (regex): (enforced messege contains)", "Content-Length: (constant Content-Length number of enforced response)"] self.EDType = JComboBox(EDStrings) self.EDType.setBounds(80, 10, 430, 30) self.EDText = JTextArea("", 5, 30) self.EDText.setBounds(80, 50, 300, 110) self.EDModel = DefaultListModel(); self.EDList = JList(self.EDModel); self.EDList.setBounds(80, 175, 300, 110) self.EDList.setBorder(LineBorder(Color.BLACK)) self.EDAdd = JButton("Add filter",actionPerformed=self.addEDFilter) self.EDAdd.setBounds(390, 85, 120, 30) self.EDDel = JButton("Remove filter",actionPerformed=self.delEDFilter) self.EDDel.setBounds(390, 210, 120, 30) self.EDPnl = JPanel() self.EDPnl.setLayout(None); self.EDPnl.setBounds(0, 0, 1000, 1000); self.EDPnl.add(EDLType) self.EDPnl.add(self.EDType) self.EDPnl.add(EDLContent) self.EDPnl.add(self.EDText) self.EDPnl.add(self.EDAdd) self.EDPnl.add(self.EDDel) self.EDPnl.add(EDLabelList) self.EDPnl.add(self.EDList) def initEnforcementDetectorUnauthorized(self): # ## init enforcement detector tab # EDLType = JLabel("Type:") EDLType.setBounds(10, 10, 140, 30) EDLContent = JLabel("Content:") EDLContent.setBounds(10, 50, 140, 30) EDLabelList = JLabel("Filter List:") EDLabelList.setBounds(10, 165, 140, 30) EDStrings = ["Headers (simple string): (enforced message headers contains)", "Headers (regex): (enforced messege headers contains)", "Body (simple string): (enforced messege body contains)", "Body (regex): (enforced messege body contains)", "Full request (simple string): (enforced messege contains)", "Full request (regex): (enforced messege contains)", "Content-Length: (constant Content-Length number of enforced response)"] self.EDTypeUnauth = JComboBox(EDStrings) self.EDTypeUnauth.setBounds(80, 10, 430, 30) self.EDTextUnauth = JTextArea("", 5, 30) self.EDTextUnauth.setBounds(80, 50, 300, 110) self.EDModelUnauth = DefaultListModel(); self.EDListUnauth = JList(self.EDModelUnauth); self.EDListUnauth.setBounds(80, 175, 300, 110) self.EDListUnauth.setBorder(LineBorder(Color.BLACK)) self.EDAddUnauth = JButton("Add filter",actionPerformed=self.addEDFilterUnauth) self.EDAddUnauth.setBounds(390, 85, 120, 30) self.EDDelUnauth = JButton("Remove filter",actionPerformed=self.delEDFilterUnauth) self.EDDelUnauth.setBounds(390, 210, 120, 30) self.EDPnlUnauth = JPanel() self.EDPnlUnauth.setLayout(None); self.EDPnlUnauth.setBounds(0, 0, 1000, 1000); self.EDPnlUnauth.add(EDLType) self.EDPnlUnauth.add(self.EDTypeUnauth) self.EDPnlUnauth.add(EDLContent) self.EDPnlUnauth.add(self.EDTextUnauth) self.EDPnlUnauth.add(self.EDAddUnauth) self.EDPnlUnauth.add(self.EDDelUnauth) self.EDPnlUnauth.add(EDLabelList) self.EDPnlUnauth.add(self.EDListUnauth) def initInterceptionFilters(self): # ## init interception filters tab # IFStrings = ["Scope items only: (Content is not required)","URL Contains (simple string): ","URL Contains (regex): ","URL Not Contains (simple string): ","URL Not Contains (regex): "] self.IFType = JComboBox(IFStrings) self.IFType.setBounds(80, 10, 430, 30) self.IFModel = DefaultListModel(); self.IFList = JList(self.IFModel); self.IFList.setBounds(80, 175, 300, 110) self.IFList.setBorder(LineBorder(Color.BLACK)) self.IFText = JTextArea("", 5, 30) self.IFText.setBounds(80, 50, 300, 110) IFLType = JLabel("Type:") IFLType.setBounds(10, 10, 140, 30) IFLContent = JLabel("Content:") IFLContent.setBounds(10, 50, 140, 30) IFLabelList = JLabel("Filter List:") IFLabelList.setBounds(10, 165, 140, 30) self.IFAdd = JButton("Add filter",actionPerformed=self.addIFFilter) self.IFAdd.setBounds(390, 85, 120, 30) self.IFDel = JButton("Remove filter",actionPerformed=self.delIFFilter) self.IFDel.setBounds(390, 210, 120, 30) self.filtersPnl = JPanel() self.filtersPnl.setLayout(None); self.filtersPnl.setBounds(0, 0, 1000, 1000); self.filtersPnl.add(IFLType) self.filtersPnl.add(self.IFType) self.filtersPnl.add(IFLContent) self.filtersPnl.add(self.IFText) self.filtersPnl.add(self.IFAdd) self.filtersPnl.add(self.IFDel) self.filtersPnl.add(IFLabelList) self.filtersPnl.add(self.IFList) def initConfigurationTab(self): # ## init configuration tab # self.prevent304 = JCheckBox("Prevent 304 Not Modified status code") self.prevent304.setBounds(290, 25, 300, 30) self.ignore304 = JCheckBox("Ignore 304/204 status code responses") self.ignore304.setBounds(290, 5, 300, 30) self.ignore304.setSelected(True) self.autoScroll = JCheckBox("Auto Scroll") #self.autoScroll.setBounds(290, 45, 140, 30) self.autoScroll.setBounds(160, 40, 140, 30) self.doUnauthorizedRequest = JCheckBox("Check unauthenticated") self.doUnauthorizedRequest.setBounds(290, 45, 300, 30) self.doUnauthorizedRequest.setSelected(True) startLabel = JLabel("Authorization checks:") startLabel.setBounds(10, 10, 140, 30) self.startButton = JButton("Autorize is off",actionPerformed=self.startOrStop) self.startButton.setBounds(160, 10, 120, 30) self.startButton.setBackground(Color(255, 100, 91, 255)) self.clearButton = JButton("Clear List",actionPerformed=self.clearList) self.clearButton.setBounds(10, 40, 100, 30) self.replaceString = JTextArea("Cookie: Insert=injected; header=here;", 5, 30) self.replaceString.setWrapStyleWord(True); self.replaceString.setLineWrap(True) self.replaceString.setBounds(10, 80, 470, 180) self.filtersTabs = JTabbedPane() self.filtersTabs.addTab("Enforcement Detector", self.EDPnl) self.filtersTabs.addTab("Detector Unauthenticated", self.EDPnlUnauth) self.filtersTabs.addTab("Interception Filters", self.filtersPnl) self.filtersTabs.addTab("Export", self.exportPnl) self.filtersTabs.setBounds(0, 280, 2000, 700) self.pnl = JPanel() self.pnl.setBounds(0, 0, 1000, 1000); self.pnl.setLayout(None); self.pnl.add(self.startButton) self.pnl.add(self.clearButton) self.pnl.add(self.replaceString) self.pnl.add(startLabel) self.pnl.add(self.autoScroll) self.pnl.add(self.ignore304) self.pnl.add(self.prevent304) self.pnl.add(self.doUnauthorizedRequest) self.pnl.add(self.filtersTabs) def initTabs(self): # ## init autorize tabs # self.logTable = Table(self) self.logTable.setAutoCreateRowSorter(True) tableWidth = self.logTable.getPreferredSize().width self.logTable.getColumn("ID").setPreferredWidth(Math.round(tableWidth / 50 * 2)) self.logTable.getColumn("URL").setPreferredWidth(Math.round(tableWidth / 50 * 24)) self.logTable.getColumn("Orig. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Modif. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Unauth. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Authorization Enforcement Status").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Authorization Unauth. Status").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._splitpane.setResizeWeight(1) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) self.scrollPane.getVerticalScrollBar().addAdjustmentListener(autoScrollListener(self)) self.menuES0 = JCheckBoxMenuItem(self._enfocementStatuses[0],True) self.menuES1 = JCheckBoxMenuItem(self._enfocementStatuses[1],True) self.menuES2 = JCheckBoxMenuItem(self._enfocementStatuses[2],True) self.menuES0.addItemListener(menuTableFilter(self)) self.menuES1.addItemListener(menuTableFilter(self)) self.menuES2.addItemListener(menuTableFilter(self)) copyURLitem = JMenuItem("Copy URL"); copyURLitem.addActionListener(copySelectedURL(self)) self.menu = JPopupMenu("Popup") self.menu.add(copyURLitem) self.menu.add(self.menuES0) self.menu.add(self.menuES1) self.menu.add(self.menuES2) self.tabs = JTabbedPane() self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self._originalrequestViewer = self._callbacks.createMessageEditor(self, False) self._originalresponseViewer = self._callbacks.createMessageEditor(self, False) self._unauthorizedrequestViewer = self._callbacks.createMessageEditor(self, False) self._unauthorizedresponseViewer = self._callbacks.createMessageEditor(self, False) self.tabs.addTab("Modified Request", self._requestViewer.getComponent()) self.tabs.addTab("Modified Response", self._responseViewer.getComponent()) self.tabs.addTab("Original Request", self._originalrequestViewer.getComponent()) self.tabs.addTab("Original Response", self._originalresponseViewer.getComponent()) self.tabs.addTab("Unauthenticated Request", self._unauthorizedrequestViewer.getComponent()) self.tabs.addTab("Unauthenticated Response", self._unauthorizedresponseViewer.getComponent()) self.tabs.addTab("Configuration", self.pnl) self.tabs.setSelectedIndex(6) self._splitpane.setRightComponent(self.tabs) def initCallbacks(self): # ## init callbacks # # customize our UI components self._callbacks.customizeUiComponent(self._splitpane) self._callbacks.customizeUiComponent(self.logTable) self._callbacks.customizeUiComponent(self.scrollPane) self._callbacks.customizeUiComponent(self.tabs) self._callbacks.customizeUiComponent(self.filtersTabs) self._callbacks.registerContextMenuFactory(self) # add the custom tab to Burp's UI self._callbacks.addSuiteTab(self) # ## Events functions # def startOrStop(self, event): if self.startButton.getText() == "Autorize is off": self.startButton.setText("Autorize is on") self.startButton.setBackground(Color.GREEN) self.intercept = 1 self._callbacks.registerHttpListener(self) else: self.startButton.setText("Autorize is off") self.startButton.setBackground(Color(255, 100, 91, 255)) self.intercept = 0 self._callbacks.removeHttpListener(self) def addEDFilter(self, event): typeName = self.EDType.getSelectedItem().split(":")[0] self.EDModel.addElement(typeName + ": " + self.EDText.getText()) def delEDFilter(self, event): index = self.EDList.getSelectedIndex(); if not index == -1: self.EDModel.remove(index); def addEDFilterUnauth(self, event): typeName = self.EDTypeUnauth.getSelectedItem().split(":")[0] self.EDModelUnauth.addElement(typeName + ": " + self.EDTextUnauth.getText()) def delEDFilterUnauth(self, event): index = self.EDListUnauth.getSelectedIndex(); if not index == -1: self.EDModelUnauth.remove(index); def addIFFilter(self, event): typeName = self.IFType.getSelectedItem().split(":")[0] self.IFModel.addElement(typeName + ": " + self.IFText.getText()) def delIFFilter(self, event): index = self.IFList.getSelectedIndex(); if not index == -1: self.IFModel.remove(index); def clearList(self, event): self._lock.acquire() oldSize = self._log.size() self._log.clear() self.fireTableRowsDeleted(0, oldSize - 1) self._lock.release() def export(self, event): if self.exportType.getSelectedItem() == "HTML": self.exportToHTML() else: self.exportToCSV() def exportToCSV(self): parentFrame = JFrame() fileChooser = JFileChooser() fileChooser.setSelectedFile(File("AutorizeReprort.csv")); fileChooser.setDialogTitle("Save Autorize Report") userSelection = fileChooser.showSaveDialog(parentFrame) if userSelection == JFileChooser.APPROVE_OPTION: fileToSave = fileChooser.getSelectedFile() enforcementStatusFilter = self.exportES.getSelectedItem() csvContent = "id\tURL\tOriginal length\tModified length\tUnauthorized length\tAuthorization Enforcement Status\tAuthorization Unauthenticated Status\n" for i in range(0,self._log.size()): if enforcementStatusFilter == "All Statuses": csvContent += "%d\t%s\t%d\t%d\t%d\t%s\t%s\n" % (self._log.get(i)._id,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, self._log.get(i)._enfocementStatus, self._log.get(i)._enfocementStatusUnauthorized) else: if (enforcementStatusFilter == self._log.get(i)._enfocementStatus) or (enforcementStatusFilter == self._log.get(i)._enfocementStatusUnauthorized): csvContent += "%d\t%s\t%d\t%d\t%d\t%s\t%s\n" % (self._log.get(i)._id,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, self._log.get(i)._enfocementStatus, self._log.get(i)._enfocementStatusUnauthorized) f = open(fileToSave.getAbsolutePath(), 'w') f.writelines(csvContent) f.close() def exportToHTML(self): parentFrame = JFrame() fileChooser = JFileChooser() fileChooser.setSelectedFile(File("AutorizeReprort.html")); fileChooser.setDialogTitle("Save Autorize Report") userSelection = fileChooser.showSaveDialog(parentFrame) if userSelection == JFileChooser.APPROVE_OPTION: fileToSave = fileChooser.getSelectedFile() enforcementStatusFilter = self.exportES.getSelectedItem() htmlContent = """<html><title>Autorize Report by Barak Tawily</title> <style> .datagrid table { border-collapse: collapse; text-align: left; width: 100%; } .datagrid {font: normal 12px/150% Arial, Helvetica, sans-serif; background: #fff; overflow: hidden; border: 1px solid #006699; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .datagrid table td, .datagrid table th { padding: 3px 10px; } .datagrid table thead th {background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; color:#FFFFFF; font-size: 15px; font-weight: bold; border-left: 1px solid #0070A8; } .datagrid table thead th:first-child { border: none; }.datagrid table tbody td { color: #00496B; border-left: 1px solid #E1EEF4;font-size: 12px;font-weight: normal; }.datagrid table tbody .alt td { background: #E1EEF4; color: #00496B; }.datagrid table tbody td:first-child { border-left: none; }.datagrid table tbody tr:last-child td { border-bottom: none; }.datagrid table tfoot td div { border-top: 1px solid #006699;background: #E1EEF4;} .datagrid table tfoot td { padding: 0; font-size: 12px } .datagrid table tfoot td div{ padding: 2px; }.datagrid table tfoot td ul { margin: 0; padding:0; list-style: none; text-align: right; }.datagrid table tfoot li { display: inline; }.datagrid table tfoot li a { text-decoration: none; display: inline-block; padding: 2px 8px; margin: 1px;color: #FFFFFF;border: 1px solid #006699;-webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; }.datagrid table tfoot ul.active, .datagrid table tfoot ul a:hover { text-decoration: none;border-color: #006699; color: #FFFFFF; background: none; background-color:#00557F;}div.dhtmlx_window_active, div.dhx_modal_cover_dv { position: fixed !important; } table { width: 100%; table-layout: fixed; } td { border: 1px solid #35f; overflow: hidden; text-overflow: ellipsis; } td.a { width: 13%; white-space: nowrap; } td.b { width: 9%; word-wrap: break-word; } </style> <body> <h1>Autorize Report<h1> <div class="datagrid"><table> <thead><tr><th width=\"3%\">ID</th><th width=\"48%\">URL</th><th width=\"9%\">Original length</th><th width=\"9%\">Modified length</th><th width=\"9%\">Unauthorized length</th><th width=\"11%\">Authorization Enforcement Status</th><th width=\"11%\">Authorization Unauthenticated Status</th></tr></thead> <tbody>""" for i in range(0,self._log.size()): color_modified = "" if self._log.get(i)._enfocementStatus == self._enfocementStatuses[0]: color_modified = "red" if self._log.get(i)._enfocementStatus == self._enfocementStatuses[1]: color_modified = "yellow" if self._log.get(i)._enfocementStatus == self._enfocementStatuses[2]: color_modified = "LawnGreen" color_unauthorized = "" if self._log.get(i)._enfocementStatusUnauthorized == self._enfocementStatuses[0]: color_unauthorized = "red" if self._log.get(i)._enfocementStatusUnauthorized == self._enfocementStatuses[1]: color_unauthorized = "yellow" if self._log.get(i)._enfocementStatusUnauthorized == self._enfocementStatuses[2]: color_unauthorized = "LawnGreen" if enforcementStatusFilter == "All Statuses": htmlContent += "<tr><td>%d</td><td><a href=\"%s\">%s</a></td><td>%d</td><td>%d</td><td>%d</td><td bgcolor=\"%s\">%s</td><td bgcolor=\"%s\">%s</td></tr>" % (self._log.get(i)._id,self._log.get(i)._url,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, color_modified, self._log.get(i)._enfocementStatus, color_unauthorized, self._log.get(i)._enfocementStatusUnauthorized) else: if (enforcementStatusFilter == self._log.get(i)._enfocementStatus) or (enforcementStatusFilter == self._log.get(i)._enfocementStatusUnauthorized): htmlContent += "<tr><td>%d</td><td><a href=\"%s\">%s</a></td><td>%d</td><td>%d</td><td>%d</td><td bgcolor=\"%s\">%s</td><td bgcolor=\"%s\">%s</td></tr>" % (self._log.get(i)._id,self._log.get(i)._url,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, color_modified, self._log.get(i)._enfocementStatus, color_unauthorized, self._log.get(i)._enfocementStatusUnauthorized) htmlContent += "</tbody></table></div></body></html>" f = open(fileToSave.getAbsolutePath(), 'w') f.writelines(htmlContent) f.close() # # implement IContextMenuFactory # def createMenuItems(self, invocation): responses = invocation.getSelectedMessages(); if responses > 0: ret = LinkedList() requestMenuItem = JMenuItem("Send request to Autorize"); cookieMenuItem = JMenuItem("Send cookie to Autorize"); requestMenuItem.addActionListener(handleMenuItems(self,responses[0], "request")) cookieMenuItem.addActionListener(handleMenuItems(self, responses[0], "cookie")) ret.add(requestMenuItem); ret.add(cookieMenuItem); return(ret); return null; # # implement ITab # def getTabCaption(self): return "Autorize" def getUiComponent(self): return self._splitpane # # extend AbstractTableModel # def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 7 def getColumnName(self, columnIndex): if columnIndex == 0: return "ID" if columnIndex == 1: return "URL" if columnIndex == 2: return "Orig. Length" if columnIndex == 3: return "Modif. Length" if columnIndex == 4: return "Unauth. Length" if columnIndex == 5: return "Authorization Enforcement Status" if columnIndex == 6: return "Authorization Unauth. Status" return "" def getColumnClass(self, columnIndex): if columnIndex == 0: return Integer if columnIndex == 1: return String if columnIndex == 2: return Integer if columnIndex == 3: return Integer if columnIndex == 4: return Integer if columnIndex == 5: return String if columnIndex == 6: return String return String def getValueAt(self, rowIndex, columnIndex): logEntry = self._log.get(rowIndex) if columnIndex == 0: return logEntry._id if columnIndex == 1: return logEntry._url.toString() if columnIndex == 2: return len(logEntry._originalrequestResponse.getResponse()) if columnIndex == 3: return len(logEntry._requestResponse.getResponse()) if columnIndex == 4: if logEntry._unauthorizedRequestResponse != None: return len(logEntry._unauthorizedRequestResponse.getResponse()) else: #return "-" return 0 if columnIndex == 5: return logEntry._enfocementStatus if columnIndex == 6: return logEntry._enfocementStatusUnauthorized return "" # # implement IMessageEditorController # this allows our request/response viewers to obtain details about the messages being displayed # def getHttpService(self): return self._currentlyDisplayedItem.getHttpService() def getRequest(self): return self._currentlyDisplayedItem.getRequest() def getResponse(self): return self._currentlyDisplayedItem.getResponse() # # implement IHttpListener # def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): #if (self.intercept == 1) and (toolFlag != self._callbacks.TOOL_EXTENDER): if (self.intercept == 1) and (toolFlag == self._callbacks.TOOL_PROXY): if self.prevent304.isSelected(): if messageIsRequest: requestHeaders = list(self._helpers.analyzeRequest(messageInfo).getHeaders()) newHeaders = list() found = 0 for header in requestHeaders: if not "If-None-Match:" in header and not "If-Modified-Since:" in header: newHeaders.append(header) found = 1 if found == 1: requestInfo = self._helpers.analyzeRequest(messageInfo) bodyBytes = messageInfo.getRequest()[requestInfo.getBodyOffset():] bodyStr = self._helpers.bytesToString(bodyBytes) messageInfo.setRequest(self._helpers.buildHttpMessage(newHeaders, bodyStr)) if not messageIsRequest: if not self.replaceString.getText() in self._helpers.analyzeRequest(messageInfo).getHeaders(): if self.ignore304.isSelected(): firstHeader = self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders()[0] if "304" in firstHeader or "204" in firstHeader: return if self.IFList.getModel().getSize() == 0: self.checkAuthorization(messageInfo,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected()) else: urlString = str(self._helpers.analyzeRequest(messageInfo).getUrl()) do_the_check = 1 for i in range(0,self.IFList.getModel().getSize()): if self.IFList.getModel().getElementAt(i).split(":")[0] == "Scope items only": currentURL = URL(urlString) if not self._callbacks.isInScope(currentURL): do_the_check = 0 if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Contains (simple string)": if self.IFList.getModel().getElementAt(i)[30:] not in urlString: do_the_check = 0 if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Contains (regex)": regex_string = self.IFList.getModel().getElementAt(i)[22:] p = re.compile(regex_string, re.IGNORECASE) if not p.search(urlString): do_the_check = 0 if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Not Contains (simple string)": if self.IFList.getModel().getElementAt(i)[34:] in urlString: do_the_check = 0 if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Not Contains (regex)": regex_string = self.IFList.getModel().getElementAt(i)[26:] p = re.compile(regex_string, re.IGNORECASE) if p.search(urlString): do_the_check = 0 if do_the_check: self.checkAuthorization(messageInfo,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected()) return def sendRequestToAutorizeWork(self,messageInfo): if messageInfo.getResponse() == None: message = self.makeMessage(messageInfo,False,False) requestResponse = self.makeRequest(messageInfo, message) self.checkAuthorization(requestResponse,self._helpers.analyzeResponse(requestResponse.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected()) else: self.checkAuthorization(messageInfo,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected()) def makeRequest(self, messageInfo, message): requestURL = self._helpers.analyzeRequest(messageInfo).getUrl() return self._callbacks.makeHttpRequest(self._helpers.buildHttpService(str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https"), message) def makeMessage(self, messageInfo, removeOrNot, authorizeOrNot): requestInfo = self._helpers.analyzeRequest(messageInfo) headers = requestInfo.getHeaders() if removeOrNot: headers = list(headers) removeHeaders = ArrayList() removeHeaders.add(self.replaceString.getText()[0:self.replaceString.getText().index(":")]) for header in headers[:]: for removeHeader in removeHeaders: if removeHeader in header: headers.remove(header) if authorizeOrNot: headers.append(self.replaceString.getText()) msgBody = messageInfo.getRequest()[requestInfo.getBodyOffset():] return self._helpers.buildHttpMessage(headers, msgBody) def checkBypass(self,oldStatusCode,newStatusCode,oldContentLen,newContentLen,filters,requestResponse): analyzedResponse = self._helpers.analyzeResponse(requestResponse.getResponse()) impression = "" if oldStatusCode == newStatusCode: if oldContentLen == newContentLen: impression = self._enfocementStatuses[0] else: auth_enforced = 1 for filter in filters: if str(filter).startswith("Headers (simple string): "): if not(filter[25:] in self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])): auth_enforced = 0 if str(filter).startswith("Headers (regex): "): regex_string = filter[17:] p = re.compile(regex_string, re.IGNORECASE) if not p.search(self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])): auth_enforced = 0 if str(filter).startswith("Body (simple string): "): if not(filter[22:] in self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])): auth_enforced = 0 if str(filter).startswith("Body (regex): "): regex_string = filter[14:] p = re.compile(regex_string, re.IGNORECASE) if not p.search(self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])): auth_enforced = 0 if str(filter).startswith("Full request (simple string): "): if not(filter[30:] in self._helpers.bytesToString(requestResponse.getResponse())): auth_enforced = 0 if str(filter).startswith("Full request (regex): "): regex_string = filter[22:] p = re.compile(regex_string, re.IGNORECASE) if not p.search(self._helpers.bytesToString(requestResponse.getResponse())): auth_enforced = 0 if str(filter).startswith("Content-Length: "): if newContentLen != filter: auth_enforced = 0 if auth_enforced: impression = self._enfocementStatuses[2] else: impression = self._enfocementStatuses[1] else: impression = self._enfocementStatuses[2] return impression def checkAuthorization(self, messageInfo, originalHeaders, checkUnauthorized): message = self.makeMessage(messageInfo,True,True) requestResponse = self.makeRequest(messageInfo, message) analyzedResponse = self._helpers.analyzeResponse(requestResponse.getResponse()) oldStatusCode = originalHeaders[0] newStatusCode = analyzedResponse.getHeaders()[0] oldContentLen = self.getContentLength(originalHeaders) newContentLen = self.getContentLength(analyzedResponse.getHeaders()) # Check unauthorized request if checkUnauthorized: messageUnauthorized = self.makeMessage(messageInfo,True,False) requestResponseUnauthorized = self.makeRequest(messageInfo, messageUnauthorized) analyzedResponseUnauthorized = self._helpers.analyzeResponse(requestResponseUnauthorized.getResponse()) statusCodeUnauthorized = analyzedResponseUnauthorized.getHeaders()[0] contentLenUnauthorized = self.getContentLength(analyzedResponseUnauthorized.getHeaders()) EDFilters = self.EDModel.toArray() impression = self.checkBypass(oldStatusCode,newStatusCode,oldContentLen,newContentLen,EDFilters,requestResponse) if checkUnauthorized: EDFiltersUnauth = self.EDModelUnauth.toArray() impressionUnauthorized = self.checkBypass(oldStatusCode,statusCodeUnauthorized,oldContentLen,contentLenUnauthorized,EDFiltersUnauth,requestResponseUnauthorized) self._lock.acquire() row = self._log.size() if checkUnauthorized: self._log.add(LogEntry(self.currentRequestNumber,self._callbacks.saveBuffersToTempFiles(requestResponse), self._helpers.analyzeRequest(requestResponse).getUrl(),messageInfo,impression,self._callbacks.saveBuffersToTempFiles(requestResponseUnauthorized),impressionUnauthorized)) # same requests not include again. else: self._log.add(LogEntry(self.currentRequestNumber,self._callbacks.saveBuffersToTempFiles(requestResponse), self._helpers.analyzeRequest(requestResponse).getUrl(),messageInfo,impression,None,"Disabled")) # same requests not include again. self.fireTableRowsInserted(row, row) self.currentRequestNumber = self.currentRequestNumber + 1 self._lock.release() def getContentLength(self, analyzedResponseHeaders): for header in analyzedResponseHeaders: if "Content-Length:" in header: return header; return "null" def getCookieFromMessage(self, messageInfo): headers = list(self._helpers.analyzeRequest(messageInfo.getRequest()).getHeaders()) for header in headers: if "Cookie:" in header: return header return None
class ConfigTab( ITab, JPanel ): def __init__( self, callbacks ): self._callbacks = callbacks self._helpers = callbacks.getHelpers() self.__initLayout__() def __initLayout__( self ): self._levelComboBox = JComboBox() levelComboBoxSize = Dimension( 300, 30 ) self._levelComboBox.setPreferredSize( levelComboBoxSize ) self._levelComboBox.setMaximumSize( levelComboBoxSize ) for level in range( 0, 6 ): self._levelComboBox.addItem( str( level ) ) self._techRenderedCheckBox = JCheckBox( 'Rendered', True ) self._techTimebasedCheckBox = JCheckBox( 'Time-based', True ) self._plugin_groups = {} for plugin in plugins: parent = plugin.__base__.__name__ if not self._plugin_groups.has_key( parent ): self._plugin_groups[ parent ] = [] self._plugin_groups[ parent ].append( plugin ) self._pluginCheckBoxes = [] for pluginGroup in self._plugin_groups.values(): for plugin in pluginGroup: self._pluginCheckBoxes.append( PluginCheckBox( plugin ) ) self._positionReplaceCheckBox = JCheckBox( 'Replace', True ) self._positionAppendCheckBox = JCheckBox( 'Append', False ) displayItems = ( { 'label': 'Level', 'components': ( self._levelComboBox, ), 'description': 'Level of code context escape to perform (1-5, Default:0).' }, { 'label': 'Techniques', 'components': ( self._techRenderedCheckBox, self._techTimebasedCheckBox, ), 'description': 'Techniques R(endered) T(ime-based blind). Default: RT.' }, { 'label': 'Template Engines', 'components': self._pluginCheckBoxes, 'description': 'Force back-end template engine to this value(s).' }, { 'label': 'Payload position', 'components': ( self._positionReplaceCheckBox, self._positionAppendCheckBox, ), 'description': 'Scan payload position. This feature only appears in BurpExtension.' } ) layout = GroupLayout( self ) self.setLayout( layout ) layout.setAutoCreateGaps( True ) layout.setAutoCreateContainerGaps( True ) labelWidth = 200 hgroup = layout.createParallelGroup( GroupLayout.Alignment.LEADING ) vgroup = layout.createSequentialGroup() for displayItem in displayItems: label = JLabel( displayItem.get( 'label' ) ) label.setToolTipText( displayItem.get( 'description' ) ) _hgroup = layout.createSequentialGroup().addComponent( label, labelWidth, labelWidth, labelWidth ) _vgroup = layout.createParallelGroup( GroupLayout.Alignment.BASELINE ).addComponent( label ) for component in displayItem.get( 'components' ): _hgroup.addComponent( component ) _vgroup.addComponent( component ) hgroup.addGroup( _hgroup ) vgroup.addGroup( _vgroup ) layout.setHorizontalGroup( hgroup ) layout.setVerticalGroup( vgroup ) def getTabCaption( self ): return 'Tplmap' def getUiComponent( self ): return self def getLevel( self ): return self._levelComboBox.getSelectedIndex() def getTechniques( self ): return '%s%s' % ( 'R' if self._techRenderedCheckBox.isSelected() else '', 'T' if self._techTimebasedCheckBox.isSelected() else '' ) def getEngines( self ): return [ checkbox.getPlugin() for checkbox in self._pluginCheckBoxes if checkbox.isSelected() ] def getPayloadPosition( self ): return { 'replace': self._positionReplaceCheckBox.isSelected(), 'append': self._positionAppendCheckBox.isSelected() }
class tag(ITab): def __init__(self, callbacks, name): self._callbacks = callbacks self.name = name def getTabCaption(self): return self.name def getUiComponent(self): return self.tabs def setFontItalic(self, label): label.setFont( Font(label.getFont().getName(), Font.ITALIC, label.getFont().getSize())) def setFontBold(self, label): label.setFont(Font('Serif', Font.BOLD, label.getFont().getSize())) # 配置界面添加 def tagLoad(self): # 创建窗口 开始 self.tabs = JTabbedPane() self.scan_type_settings = JPanel(GridBagLayout()) c = GridBagConstraints() # 界面选项卡加载 self.tag_1(c) self.tag_2(c) self.tag_3(c) # 添加选项卡 self.tabs.addTab(u'扫描类型设置', self.scan_type_settings) self._callbacks.customizeUiComponent(self.tabs) self._callbacks.addSuiteTab(self) # 选项卡1-标签1-ui def tag_1(self, c): # 创建 检查框 self.is_scan_get_start_box = JCheckBox(u'是否扫描GET类型的参数(推荐打勾)', XssConfig.IS_SCAN_GET_START) self.setFontBold(self.is_scan_get_start_box) self.is_scan_get_start_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 1 self.scan_type_settings.add(self.is_scan_get_start_box, c) # 选项卡1-标签2-ui def tag_2(self, c): # 创建 检查框 self.is_scan_post_start_box = JCheckBox(u'是否扫描POST类型的参数(推荐打勾)', XssConfig.IS_SCAN_POST_START) self.setFontBold(self.is_scan_post_start_box) self.is_scan_post_start_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 2 self.scan_type_settings.add(self.is_scan_post_start_box, c) def tag_3(self, c): # 创建 检查框 self.is_scan_url_path_folders_box = JCheckBox( u'扫描URL路径作为参数', XssConfig.IS_SCAN_URL_PATH_FOLDERS) self.setFontBold(self.is_scan_url_path_folders_box) self.is_scan_url_path_folders_box.setForeground(Color(0, 0, 153)) c.insets = Insets(5, 5, 5, 5) c.gridx = 0 c.gridy = 3 self.scan_type_settings.add(self.is_scan_url_path_folders_box, c) def getScanTypeList(self): type_list = [] if self.is_scan_get_start_box.isSelected(): type_list.append(0) if self.is_scan_post_start_box.isSelected(): type_list.append(1) if self.is_scan_url_path_folders_box.isSelected(): type_list.append(33) type_list.append(37) return type_list
class BurpExtender(IBurpExtender, IIntruderPayloadGeneratorFactory, ITab): name = "FURR - Fuzz yoUR Request" args = [] zzuf = "" radamsa = "" _jTabbedPane = JTabbedPane() _jPanel = JPanel() _jAboutPanel = JPanel() _jPanelConstraints = GridBagConstraints() aboutText = "<h1>How-to</h1><br>" \ "In order to use FURR you MUST install zzuf & radamsa from source using: <br>" \ "<pre><b>git clone https://github.com/samhocevar/zzuf.git && cd zzuf && ./bootstrap && ./configure && make && sudo make install</b></pre>" \ "<pre><b>git clone https://github.com/aoh/radamsa.git && cd radamsa && make && sudo make install</b></pre>" \ "Once done zzuf and radamsa should be in your PATH so try:<br>" \ "<pre><b>echo 'fuzzme!' | zuff -r 0.01 -s 1</b></pre>" \ "<pre><b>echo 'fuzzme!' | radamsa</b></pre>" \ "If you get a different result from the original 'fuzzme' than you're ready to go!<br><br>" \ "<h1>About me</h1><br>" \ "I'm a security expert working @ Consulthink S.p.A. passionate about fuzzing and exploitation!<br>" \ "<h1>About FURR</h1><br>" \ "FURR is still a 'work in progress' tool it will be upgraded every time is possible so stay tuned!<br>" \ "<h1>How to use</h1><br>" \ "It's pretty easy:<br><ul>" \ "<li> Go to FURR Configuration and click '<b>Set Configuration</b>'</li>" \ "<li> Send the request to the Intruder </li>" \ "<li> Select the entire request and add as position </li>" \ "<li> Set Payload type to '<b>Extension generated</b>' </li>" \ "<li> Set Generator to '<b>FURR</b>' </li>" \ "<li> Disable automatic URL-Encode </li>" \ "<li> Fuzz! </li></ul><br><br>" \ "<center><h2>Happy fuzzing!</h2></center>" def which(self, bin): find_bin = subprocess.Popen(["/usr/bin/which", bin], stdout=subprocess.PIPE) find_bin.wait() binary = find_bin.stdout.read().replace("\n", "").replace("\r", "") if not binary: sys.stderr.write( "Unable to find {0} in path! Please symlink {1} to /usr/local/bin/{2}" .format(bin, bin, bin)) return "" else: return binary def registerExtenderCallbacks(self, callbacks): self.zzuf = self.which("zzuf") self.radamsa = self.which("radamsa") self._callbacks = callbacks self._helpers = callbacks.getHelpers() callbacks.setExtensionName(self.name) callbacks.registerIntruderPayloadGeneratorFactory(self) callbacks.addSuiteTab(self) self.initPanelConfig() self._jTabbedPane.addTab("About", self._jAboutPanel) self._jTabbedPane.addTab("Configuration", self._jPanel) return def getUiComponent(self): return self._jTabbedPane def getTabCaption(self): return "FURR" def initPanelConfig(self): self._jPanel.setBounds(0, 0, 1000, 1000) self._jPanel.setLayout(GridBagLayout()) self._jAboutPanel.setBounds(0, 0, 1000, 1000) self._jAboutPanel.setLayout(GridBagLayout()) self._jLabelTitle = JLabel( "<html><body><b><center>Fuzzing options</center></b><br></body></html>" ) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 0 self._jPanel.add(self._jLabelTitle, self._jPanelConstraints) self._jCheckBoxMethod = JCheckBox("Request Method") self._jCheckBoxMethod.setSelected(True) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 1 self._jPanel.add(self._jCheckBoxMethod, self._jPanelConstraints) self._jCheckBoxPath = JCheckBox("Request Path") self._jCheckBoxPath.setSelected(True) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 2 self._jPanel.add(self._jCheckBoxPath, self._jPanelConstraints) self._jCheckBoxHTTP = JCheckBox("HTTP String") self._jCheckBoxHTTP.setSelected(True) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 3 self._jPanel.add(self._jCheckBoxHTTP, self._jPanelConstraints) self._jCheckBoxHTTPver = JCheckBox("HTTP Version") self._jCheckBoxHTTPver.setSelected(True) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 4 self._jPanel.add(self._jCheckBoxHTTPver, self._jPanelConstraints) self._jCheckBoxHeaderName = JCheckBox("Header Name") self._jCheckBoxHeaderName.setSelected(True) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 5 self._jPanel.add(self._jCheckBoxHeaderName, self._jPanelConstraints) self._jCheckBoxHeaderValue = JCheckBox("Header Content") self._jCheckBoxHeaderValue.setSelected(True) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 6 self._jPanel.add(self._jCheckBoxHeaderValue, self._jPanelConstraints) self._jCheckBoxBodyValue = JCheckBox("Body Content") self._jCheckBoxBodyValue.setSelected(True) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 7 self._jPanel.add(self._jCheckBoxBodyValue, self._jPanelConstraints) self._jCheckBoxParamName = JCheckBox("Parameters Name") self._jCheckBoxParamName.setSelected(True) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 8 self._jPanel.add(self._jCheckBoxParamName, self._jPanelConstraints) self._jCheckBoxParamValue = JCheckBox("Parameters Value") self._jCheckBoxParamValue.setSelected(True) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 9 self._jPanel.add(self._jCheckBoxParamValue, self._jPanelConstraints) self._jCheckBoxAllRequest = JCheckBox("Entire Request") self._jCheckBoxAllRequest.setSelected(True) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 10 self._jPanel.add(self._jCheckBoxAllRequest, self._jPanelConstraints) self._jLabelSpace = JLabel( "<html><body><b><center> </center></b><br></body></html>") self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 11 self._jPanel.add(self._jLabelSpace, self._jPanelConstraints) self._jButtonSetCommandLine = JButton( 'Set Configuration', actionPerformed=self.setCommandLine) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 12 self._jPanelConstraints.gridwidth = 2 self._jPanel.add(self._jButtonSetCommandLine, self._jPanelConstraints) self._jButtonReset = JButton('Reset all', actionPerformed=self.resetAll) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 13 self._jPanelConstraints.gridwidth = 2 self._jPanel.add(self._jButtonReset, self._jPanelConstraints) self._jLabelAbout = JLabel("<html><body>%s</body></html>" % self.aboutText) self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL self._jPanelConstraints.gridx = 0 self._jPanelConstraints.gridy = 0 self._jAboutPanel.add(self._jLabelAbout, self._jPanelConstraints) def resetAll(self, event=None): self._jCheckBoxMethod.setSelected(True) self._jCheckBoxPath.setSelected(True) self._jCheckBoxHTTP.setSelected(True) self._jCheckBoxHTTPver.setSelected(True) self._jCheckBoxHeaderName.setSelected(True) self._jCheckBoxHeaderValue.setSelected(True) self._jCheckBoxBodyValue.setSelected(True) self._jCheckBoxParamName.setSelected(True) self._jCheckBoxParamValue.setSelected(True) self._jCheckBoxAllRequest.setSelected(True) def setCommandLine(self, event=None): method = self._jCheckBoxMethod.isSelected() path = self._jCheckBoxPath.isSelected() httpstring = self._jCheckBoxHTTP.isSelected() httpver = self._jCheckBoxHTTPver.isSelected() headername = self._jCheckBoxHeaderName.isSelected() headervalue = self._jCheckBoxHeaderValue.isSelected() bodyvalue = self._jCheckBoxBodyValue.isSelected() paramname = self._jCheckBoxParamName.isSelected() paramvalue = self._jCheckBoxParamValue.isSelected() allrequest = self._jCheckBoxAllRequest.isSelected() self.tokens = [] if method: self.tokens.append( re.compile("^(POST|GET|HEAD|OPTIONS|DELETE|TRACE|PUT|UPDATE)", re.MULTILINE)) if path: self.tokens.append(re.compile("^[A-Z]+\s(.*)\s+HTTP", re.MULTILINE)) if httpstring: self.tokens.append(re.compile("\s(HTTP)", re.MULTILINE)) if httpver: self.tokens.append(re.compile("HTTP/([0-9.]+)", re.MULTILINE)) if headername: self.tokens.append(re.compile("(.*):\s", re.MULTILINE)) if headervalue: self.tokens.append(re.compile(":\s(.*)", re.MULTILINE)) if bodyvalue: self.tokens.append(re.compile("\r\n\r\n(.*)", re.MULTILINE)) if paramname: self.tokens.append( re.compile("([A-Za-z0-9]+)=[\w\d%%.-_\\/\(\)\[\]\*]+", re.MULTILINE)) self.tokens.append( re.compile("[A-Za-z0-9]+=\"([\x23-\x97\s!]+)\"", re.MULTILINE)) if paramvalue: self.tokens.append( re.compile("[A-Za-z0-9]+=([\w\d%%.-_\\/\(\)\[\]\*]+)", re.MULTILINE)) self.tokens.append(re.compile("\r\n\r\n(.*)\r\n--", re.MULTILINE)) if allrequest: self.tokens.append(re.compile("([\d\D\w\W]+)", re.MULTILINE)) JOptionPane.showMessageDialog(None, "Successfully configured!") def getGeneratorName(self): return "FURR" def createNewInstance(self, attack): return HTTPFuzzer(self, attack, self.zzuf, self.radamsa, self.tokens)
class UIGlobalSettingsPanel(IngestModuleGlobalSettingsPanel): def __init__(self): self.save_file_cbox = JCheckBox(C_LABEL_INFO_AUTOPSY_TEMP) ## "Save copied images outside of AUTOPSY's temp" self.textInputs = { '0': JTextField('', 30), '1': JTextField('', 30), '2': JTextField('', 30) } self.buttons = { '0': JButton("Choose file", actionPerformed=self.chooseFolder), '1': JButton("Choose file", actionPerformed=self.chooseFolder), '2': JButton("Choose file", actionPerformed=self.chooseFolder) } self.initComponents() self.load() def checkBoxEvent(self, event): self.save_files = self.save_file_cbox.isSelected() def saveSettings(self): all_paths = {} for code in self.textInputs: all_paths[code] = self.textInputs[code].text with open(GLOBAL_CONFIGURATION_PATH, "w") as out: json.dump({ "save_files": self.save_file_cbox.isSelected(), "paths": all_paths }, out) def load(self): # Load settings from file if os.path.exists(GLOBAL_CONFIGURATION_PATH): with open(GLOBAL_CONFIGURATION_PATH, "r") as out: content = json.load(out) # self.save_file_cbox.setSelected(content['save_files']) self.textInputs['0'].text = content['paths']['0'] self.textInputs['1'].text = content['paths']['1'] self.textInputs['2'].text = content['paths']['2'] def chooseFolder(self, e): button = e.getSource() code = button.getActionCommand() fileChooser = JFileChooser() fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY) ret = fileChooser.showDialog(self, "Choose folder") if ret == JFileChooser.APPROVE_OPTION: ff = fileChooser.getSelectedFile() path = ff.getCanonicalPath() self.textInputs[code].text = path def initComponents(self): self.setLayout(None) self.setPreferredSize(Dimension(500, 400)) lblNewLabel = JLabel("Detector model path:") lblNewLabel.setBounds(45, 144, 227, 16) self.add(lblNewLabel) lblNewLabel_1 = JLabel("Recognition model path:") lblNewLabel_1.setBounds(44, 210, 228, 16) self.add(lblNewLabel_1) lblNewLabel_2 = JLabel("Shape predictor model path:") lblNewLabel_2.setBounds(45, 275, 227, 16) self.add(lblNewLabel_2) self.textInputs['0'].setBounds(44, 173, 228, 22) self.textInputs['0'].setColumns(30) self.add(self.textInputs['0']) self.textInputs['1'].setColumns(30) self.textInputs['1'].setBounds(44, 238, 228, 22) self.add(self.textInputs['1']) self.textInputs['2'].setColumns(30) self.textInputs['2'].setBounds(45, 304, 228, 22) self.add(self.textInputs['2']) self.buttons['0'].setBounds(284, 172, 97, 25) self.buttons['0'].setActionCommand("0") self.add(self.buttons['0']) self.buttons['1'].setBounds(284, 237, 97, 25) self.buttons['1'].setActionCommand("1") self.add(self.buttons['1']) self.buttons['2'].setBounds(284, 303, 97, 25) self.buttons['2'].setActionCommand("2") self.add(self.buttons['2']) self.save_file_cbox = JCheckBox(C_LABEL_INFO_AUTOPSY_TEMP) self.save_file_cbox.setBounds(45, 98, 300, 25) self.add(self.save_file_cbox)
class BurpExtender(IBurpExtender, IHttpListener, IContextMenuFactory, ITab): def registerExtenderCallbacks(self, callbacks): self.lastTimestamp = None self.callbacks = callbacks self.helpers = callbacks.getHelpers() sys.stdout = callbacks.getStdout() l = self.callbacks.loadExtensionSetting self.es_host = l("elasticburp.host") or 'localhost' self.es_index = l("elasticburp.index") or 'burp' self.whitelist = l("elasticburp.whitelist") or '' tools = l("elasticburp.tools") self.tools = int(tools) if tools is not None else 511 self.log_level = l("elasticburp.logLevel") or 'INFO' logger.setLevel(getattr(logging, self.log_level)) self.callbacks.setExtensionName("ElasticBurp") self.callbacks.registerHttpListener(self) self.callbacks.registerContextMenuFactory(self) self.callbacks.addSuiteTab(self) def processHttpMessage(self, tool, isRequest, msg): if (tool & self.tools): logger.warning('Indexing single document') doc = self.create_document(msg) if doc is not None: doc.save() def create_document(self, msg): http_service = msg.getHttpService() host = http_service.getHost() if self.whitelist and self.whitelist not in host: logger.warning('Skipping {} because it\'s not in ' 'the whitelist'.format(host)) return doc = ElasticBurpDocument( self.es_index, self.es_host, http_service.getProtocol(), host, http_service.getPort()) request = msg.getRequest() response = msg.getResponse() if request: req = self.helpers.analyzeRequest(msg) doc.request['method'] = req.getMethod() doc.request['url'] = req.getUrl().toString() logger.info('Indexing {} request from {}'.format( doc.request['method'], doc.request['url'])) doc.add_request_headers(req.getHeaders()) parameters = req.getParameters() for parameter in parameters: doc.add_request_parameter( PARAMETER_TYPES[parameter.getType()], parameter.getName(), parameter.getValue()) ct = CONTENT_TYPES[req.getContentType()] doc.request['content_type'] = ct bodyOffset = req.getBodyOffset() doc.request['body'] = request[bodyOffset:].tostring().decode( "ascii", "replace") if response: iResponse = self.helpers.analyzeResponse(response) doc.response['status'] = iResponse.getStatusCode() doc.response['content_type'] = iResponse.getStatedMimeType() doc.response['inferred_content_type'] = \ iResponse.getInferredMimeType() logger.info('Indexing {} response'.format(doc.response['status'])) doc.add_response_headers(iResponse.getHeaders()) cookies = iResponse.getCookies() for cookie in cookies: expCookie = cookie.getExpiration() expiration = datetime.fromtimestamp(expCookie.time / 1000) if \ expCookie else None doc.add_response_cookie( cookie.getName(), cookie.getValue(), cookie.getDomain(), cookie.getPath(), expiration) bodyOffset = iResponse.getBodyOffset() doc.response['body'] = response[bodyOffset:].tostring().decode( "ascii", "replace") return doc def getTabCaption(self): return "ElasticBurp" def getUiComponent(self): ui_panel = JPanel() ui_panel.setLayout(BoxLayout(ui_panel, BoxLayout.PAGE_AXIS)) ui_host_line = JPanel() ui_host_line.setLayout(BoxLayout(ui_host_line, BoxLayout.LINE_AXIS)) ui_host_line.setAlignmentX(JPanel.LEFT_ALIGNMENT) ui_host_line.add(JLabel("ElasticSearch Host: ")) self.ui_es_host = JTextField(40) self.ui_es_host.setMaximumSize(self.ui_es_host.getPreferredSize()) self.ui_es_host.setText(self.es_host) ui_host_line.add(self.ui_es_host) ui_panel.add(ui_host_line) ui_index_line = JPanel() ui_index_line.setLayout(BoxLayout(ui_index_line, BoxLayout.LINE_AXIS)) ui_index_line.setAlignmentX(JPanel.LEFT_ALIGNMENT) ui_index_line.add(JLabel("ElasticSearch Index: ")) self.ui_es_index = JTextField(40) self.ui_es_index.setText(self.es_index) self.ui_es_index.setMaximumSize(self.ui_es_index.getPreferredSize()) ui_index_line.add(self.ui_es_index) ui_panel.add(ui_index_line) ui_whitelist_line = JPanel() ui_whitelist_line.setLayout( BoxLayout(ui_whitelist_line, BoxLayout.LINE_AXIS)) ui_whitelist_line.setAlignmentX(JPanel.LEFT_ALIGNMENT) ui_whitelist_line.add(JLabel("Host whitelist: ")) self.ui_whitelist = JTextField(40) self.ui_whitelist.setText(self.whitelist) self.ui_whitelist.setMaximumSize(self.ui_whitelist.getPreferredSize()) ui_whitelist_line.add(self.ui_whitelist) ui_panel.add(ui_whitelist_line) ui_tools_panel = JPanel() ui_tools_panel.setLayout( BoxLayout(ui_tools_panel, BoxLayout.LINE_AXIS)) ui_tools_panel.setAlignmentX(JPanel.LEFT_ALIGNMENT) self.ui_tool_suite = JCheckBox( "Suite", self.tools & ECallbacks.TOOL_SUITE != 0) ui_tools_panel.add(self.ui_tool_suite) ui_tools_panel.add(Box.createRigidArea(Dimension(10, 0))) self.ui_tool_target = JCheckBox( "Target", self.tools & ECallbacks.TOOL_TARGET != 0) ui_tools_panel.add(self.ui_tool_target) ui_tools_panel.add(Box.createRigidArea(Dimension(10, 0))) self.ui_tool_proxy = JCheckBox( "Proxy", self.tools & ECallbacks.TOOL_PROXY != 0) ui_tools_panel.add(self.ui_tool_proxy) ui_tools_panel.add(Box.createRigidArea(Dimension(10, 0))) self.ui_tool_spider = JCheckBox( "Spider", self.tools & ECallbacks.TOOL_SPIDER != 0) ui_tools_panel.add(self.ui_tool_spider) ui_tools_panel.add(Box.createRigidArea(Dimension(10, 0))) self.ui_tool_scanner = JCheckBox( "Scanner", self.tools & ECallbacks.TOOL_SCANNER != 0) ui_tools_panel.add(self.ui_tool_scanner) ui_tools_panel.add(Box.createRigidArea(Dimension(10, 0))) self.ui_tool_intruder = JCheckBox( "Intruder", self.tools & ECallbacks.TOOL_INTRUDER != 0) ui_tools_panel.add(self.ui_tool_intruder) ui_tools_panel.add(Box.createRigidArea(Dimension(10, 0))) self.ui_tool_repeater = JCheckBox( "Repeater", self.tools & ECallbacks.TOOL_REPEATER != 0) ui_tools_panel.add(self.ui_tool_repeater) ui_tools_panel.add(Box.createRigidArea(Dimension(10, 0))) self.ui_tool_sequencer = JCheckBox( "Sequencer", self.tools & ECallbacks.TOOL_SEQUENCER != 0) ui_tools_panel.add(self.ui_tool_sequencer) ui_tools_panel.add(Box.createRigidArea(Dimension(10, 0))) self.ui_tool_extender = JCheckBox( "Extender", self.tools & ECallbacks.TOOL_EXTENDER != 0) ui_tools_panel.add(self.ui_tool_extender) ui_panel.add(ui_tools_panel) ui_panel.add(Box.createRigidArea(Dimension(0, 10))) ui_log_line = JPanel() ui_log_line.setLayout(BoxLayout(ui_log_line, BoxLayout.LINE_AXIS)) ui_log_line.setAlignmentX(JPanel.LEFT_ALIGNMENT) ui_debug = JRadioButton("DEBUG", self.log_level == 'DEBUG') ui_log_line.add(ui_debug) ui_log_line.add(Box.createRigidArea(Dimension(10, 0))) ui_info = JRadioButton("INFO", self.log_level == 'INFO') ui_log_line.add(ui_info) ui_log_line.add(Box.createRigidArea(Dimension(10, 0))) ui_warning = JRadioButton("WARNING", self.log_level == 'WARNING') ui_log_line.add(ui_warning) ui_log_line.add(Box.createRigidArea(Dimension(10, 0))) ui_error = JRadioButton("ERROR", self.log_level == 'ERROR') ui_log_line.add(ui_error) ui_log_line.add(Box.createRigidArea(Dimension(10, 0))) ui_critical = JRadioButton( "CRITICAL", self.log_level == 'CRITICAL') ui_log_line.add(ui_critical) ui_log_line.add(Box.createRigidArea(Dimension(10, 0))) ui_panel.add(ui_log_line) ui_panel.add(Box.createRigidArea(Dimension(0, 10))) self.ui_log_level = ButtonGroup() self.ui_log_level.add(ui_debug) self.ui_log_level.add(ui_info) self.ui_log_level.add(ui_warning) self.ui_log_level.add(ui_error) self.ui_log_level.add(ui_critical) ui_buttons_line = JPanel() ui_buttons_line.setLayout( BoxLayout(ui_buttons_line, BoxLayout.LINE_AXIS)) ui_buttons_line.setAlignmentX(JPanel.LEFT_ALIGNMENT) ui_buttons_line.add( JButton("Save config", actionPerformed=self.save_config)) ui_panel.add(ui_buttons_line) return ui_panel def save_config(self, event): logger.warning('Saving changes in config') self.es_host = self.ui_es_host.getText() self.es_index = self.ui_es_index.getText() self.whitelist = self.ui_whitelist.getText() self.tools = int( (self.ui_tool_suite.isSelected() and ECallbacks.TOOL_SUITE) | (self.ui_tool_target.isSelected() and ECallbacks.TOOL_TARGET) | (self.ui_tool_proxy.isSelected() and ECallbacks.TOOL_PROXY) | (self.ui_tool_spider.isSelected() and ECallbacks.TOOL_SPIDER) | (self.ui_tool_scanner.isSelected() and ECallbacks.TOOL_SCANNER) | (self.ui_tool_intruder.isSelected() and ECallbacks.TOOL_INTRUDER) | (self.ui_tool_repeater.isSelected() and ECallbacks.TOOL_REPEATER) | (self.ui_tool_sequencer.isSelected() and ECallbacks.TOOL_SEQUENCER) | (self.ui_tool_extender.isSelected() and ECallbacks.TOOL_EXTENDER)) logger.debug('Changing tools in config to %d' % self.tools) for button in self.ui_log_level.getElements(): if button.isSelected(): logger.debug('Changing logLevel to %s' % button.getText()) self.log_level = button.getText() s = self.callbacks.saveExtensionSetting s("elasticburp.host", self.es_host) s("elasticburp.index", self.es_index) s("elasticburp.tools", str(self.tools)) s("elasticburp.logLevel", self.log_level) s("elasticburp.whitelist", self.whitelist) logger.setLevel(getattr(logging, self.log_level))
class MandersPlugin(ImageListener, WindowAdapter): def __init__(self): self.imp = None self.preview = None self.createMainWindow() self.cells = None self.files = [] self.results = ResultsTable() ImagePlus.addImageListener(self) self.selectInputDir() self.selectOutputDir() self.pairs = [] self.methods = [] self.processNextFile() def selectInputDir(self): inputDialog = DirectoryChooser("Please select a directory contaning your images") inputDir = inputDialog.getDirectory() for imageFile in os.listdir(inputDir): self.files.append(inputDir + imageFile) def selectOutputDir(self): outputDialog = DirectoryChooser("Please select a directory to save your results") self.outputDir = outputDialog.getDirectory() def closeImage(self): if self.imp is not None: self.imp.close() self.imp = None if self.preview is not None: self.preview.close() self.preview = None def openImage(self, imageFile): try: images = BF.openImagePlus(imageFile) self.imp = images[0] except UnknownFormatException: return None if self.imp.getNChannels() < 2: IJ.error("Bad image format", "Image must contain at lease 2 channels!") return None if not self.pairs or \ not self.methods: self.getOptionsDialog(self.imp) title = self.imp.title self.imp.title = title[:title.rfind('.')] return self.imp def getOptionsDialog(self, imp): thr_methods = ["None", "Default", "Huang", "Intermodes", "IsoData", "Li", "MaxEntropy","Mean", "MinError(I)", "Minimum", "Moments", "Otsu", "Percentile", "RenyiEntropy", "Shanbhag" , "Triangle", "Yen"] gd = GenericDialog("Please select channels to collocalize") for i in range(1, imp.getNChannels() + 1): gd.addChoice("Threshold method for channel %i" % i, thr_methods, "None") gd.showDialog() if gd.wasCanceled(): self.exit() channels = [] for i in range(1, imp.getNChannels() + 1): method = gd.getNextChoice() self.methods.append(method) if method != "None": channels.append(i) for x in channels: for y in channels: if x < y: self.pairs.append((x, y)) def processNextFile(self): if self.files: imageFile = self.files.pop(0) return self.processFile(imageFile) else: return False def processFile(self, imageFile): imp = self.openImage(imageFile) if imp is not None: cell = Cell(imp.NSlices, 1) self.cells = DelegateListModel([]) self.cells.append(cell) self.showMainWindow(self.cells) if self.checkbox3D.isSelected(): self.displayImage(imp) else: self.displayImage(imp, False) self.preview = self.previewImage(imp) self.displayImage(self.preview) return True else: return self.processNextFile() def displayImage(self, imp, show = True): imp.setDisplayMode(IJ.COMPOSITE) enhancer = ContrastEnhancer() enhancer.setUseStackHistogram(True) splitter = ChannelSplitter() for c in range(1, imp.getNChannels() + 1): imp.c = c enhancer.stretchHistogram(imp, 0.35) if show: imp.show() def previewImage(self, imp): roi = imp.getRoi() splitter = ChannelSplitter() channels = [] for c in range(1, imp.getNChannels() + 1): channel = ImagePlus("Channel %i" % c, splitter.getChannel(imp, c)) projector = ZProjector(channel) projector.setMethod(ZProjector.MAX_METHOD) projector.doProjection() channels.append(projector.getProjection()) image = RGBStackMerge.mergeChannels(channels, False) image.title = imp.title + " MAX Intensity" image.luts = imp.luts imp.setRoi(roi) return image def getCroppedChannels(self, imp, cell): splitter = ChannelSplitter() imp.setRoi(None) if cell.mode3D: cropRoi = cell.getCropRoi() else: cropRoi = cell.roi if cropRoi is None: return None crop = cropRoi.getBounds() channels = [] for c in range(1, imp.getNChannels() + 1): slices = ImageStack(crop.width, crop.height) channel = splitter.getChannel(imp, c) for z in range(1, channel.getSize() + 1): zslice = channel.getProcessor(z) zslice.setRoi(cropRoi) nslice = zslice.crop() if cell.mode3D: oroi = cell.slices[z - 1].roi else: oroi = cell.roi if oroi is not None: roi = oroi.clone() bounds = roi.getBounds() roi.setLocation(bounds.x - crop.x, bounds.y - crop.y) nslice.setColor(Color.black) nslice.fillOutside(roi) slices.addSlice(nslice) channels.append(ImagePlus("Channel %i" % c, slices)) return channels def getThreshold(self, imp, method): thresholder = Auto_Threshold() duplicator = Duplicator() tmp = duplicator.run(imp) return thresholder.exec(tmp, method, False, False, True, False, False, True) def getContainer(self, impA, impB): imgA = ImagePlusAdapter.wrap(impA) imgB = ImagePlusAdapter.wrap(impB) return DataContainer(imgA, imgB, 1, 1, "imageA", "imageB") def getManders(self, imp, cell): ### Crop channels according to cell mask channels = self.getCroppedChannels(imp, cell) if channels is None: return None ### Calculate channel thresholds thrs = [] thrimps = [] for c, method in enumerate(self.methods): if method != "None": thr, thrimp = self.getThreshold(channels[c], method) else: thr, thrimp = None, None thrs.append(thr) thrimps.append(thrimp) ### Calculate manders colocalization manders = MandersColocalization() raws = [] thrds = [] for chA, chB in self.pairs: container = self.getContainer(channels[chA - 1], channels[chB - 1]) img1 = container.getSourceImage1() img2 = container.getSourceImage2() mask = container.getMask() cursor = TwinCursor(img1.randomAccess(), img2.randomAccess(), Views.iterable(mask).localizingCursor()) rtype = img1.randomAccess().get().createVariable() raw = manders.calculateMandersCorrelation(cursor, rtype) rthr1 = rtype.copy() rthr2 = rtype.copy() rthr1.set(thrs[chA - 1]) rthr2.set(thrs[chB - 1]) cursor.reset() thrd = manders.calculateMandersCorrelation(cursor, rthr1, rthr2, ThresholdMode.Above) raws.append(raw) thrds.append(thrd) return (channels, thrimps, thrs, raws, thrds) def saveMultichannelImage(self, title, channels, luts): tmp = RGBStackMerge.mergeChannels(channels, False) tmp.luts = luts saver = FileSaver(tmp) saver.saveAsTiffStack(self.outputDir + title + ".tif") tmp.close() def createMainWindow(self): self.frame = JFrame('Select cells and ROIs', defaultCloseOperation = JFrame.DISPOSE_ON_CLOSE ) self.frame.setLayout(GridBagLayout()) self.frame.addWindowListener(self) self.frame.add(JLabel("Cells"), GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, Insets(5, 2, 2, 0), 0, 0 )) self.cellList = JList(DelegateListModel([]), selectionMode = ListSelectionModel.SINGLE_SELECTION, cellRenderer = MyRenderer(), selectedIndex = 0, valueChanged = self.selectCell ) self.frame.add(JScrollPane(self.cellList), GridBagConstraints(0, 1, 1, 5, .5, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, Insets(0, 2, 2, 0), 0, 0 )) self.frame.add(JButton('Add cell', actionPerformed = self.addCell), GridBagConstraints(1, 2, 1, 2, 0, .25, GridBagConstraints.CENTER, GridBagConstraints.NONE, Insets(0, 0, 0, 0), 0, 0 )) self.frame.add(JButton('Remove cell', actionPerformed = self.removeCell), GridBagConstraints(1, 4, 1, 2, 0, .25, GridBagConstraints.CENTER, GridBagConstraints.NONE, Insets(0, 5, 0, 5), 0, 0 )) self.frame.add(JLabel("Slices"), GridBagConstraints(0, 6, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, Insets(5, 2, 2, 0), 0, 0 )) self.sliceList = JList(DelegateListModel([]), selectionMode = ListSelectionModel.SINGLE_SELECTION, cellRenderer = MyRenderer(), selectedIndex = 0, valueChanged = self.selectSlice ) self.frame.add(JScrollPane(self.sliceList), GridBagConstraints(0, 7, 1, 5, .5, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, Insets(0, 2, 2, 0), 0, 0 )) self.frame.add(JButton('Update ROI', actionPerformed = self.updateSlice), GridBagConstraints(1, 8, 1, 2, 0, .25, GridBagConstraints.CENTER, GridBagConstraints.NONE, Insets(0, 0, 0, 0), 0, 0 )) self.frame.add(JButton('Done', actionPerformed = self.doneSelecting), GridBagConstraints(1, 10, 1, 2, 0, .25, GridBagConstraints.CENTER, GridBagConstraints.NONE, Insets(0, 0, 0, 0), 0, 0 )) self.checkbox3D = JCheckBox('3D selection mode', True, actionPerformed=self.toggle3D) self.frame.add(self.checkbox3D, GridBagConstraints(0, 13, 2, 1, 0, 1, GridBagConstraints.WEST, GridBagConstraints.NONE, Insets(0, 0, 0, 0), 0, 0 )) def showMainWindow(self, cells = None): if cells is not None: self.cellList.model = cells if cells: self.cellList.selectedIndex = 0 self.frame.pack() self.frame.visible = True def hideMainWindow(self): self.frame.visible = False def closeMainWindow(self): self.frame.dispose() def toggle3D(self, event): mode3D = self.checkbox3D.isSelected() if mode3D: self.sliceList.enabled = True if self.imp is not None: self.imp.show() if self.preview is not None: self.preview.hide() else: self.sliceList.enabled = False if self.preview is None: self.preview = self.previewImage(self.imp) self.displayImage(self.preview) else: self.preview.show() if self.imp is not None: self.imp.hide() selectedCell = self.cellList.selectedIndex if selectedCell >= 0: cell = self.cells[selectedCell] self.sliceList.model = cell.slices self.sliceList.selectedIndex = 0 def addCell(self, event): size = len(self.cells) if (size > 0): last = self.cells[size - 1] n = last.n + 1 else: n = 1 self.cells.append(Cell(self.imp.NSlices, n)) self.cellList.selectedIndex = size def removeCell(self, event): selected = self.cellList.selectedIndex if selected >= 0: self.cells.remove(self.cells[selected]) if (selected >= 1): self.cellList.selectedIndex = selected - 1 else: self.cellList.selectedIndex = 0 def selectCell(self, event): selected = self.cellList.selectedIndex if selected >= 0: cell = self.cells[selected] self.sliceList.model = cell.slices self.sliceList.selectedIndex = 0 else: self.sliceList.model = DelegateListModel([]) if self.preview is not None: self.preview.setRoi(cell.roi) def selectSlice(self, event): selectedCell = self.cellList.selectedIndex selectedSlice = self.sliceList.selectedIndex if selectedCell >= 0 and selectedSlice >= 0: cell = self.cells[selectedCell] image = self.imp mode3D = self.checkbox3D.isSelected() if image is not None and cell is not None and mode3D: roi = cell.slices[selectedSlice].roi if (image.z - 1 != selectedSlice): image.z = selectedSlice + 1 image.setRoi(roi, True) if self.preview is not None and not mode3D: self.preview.setRoi(cell.roi, True) def updateSlice(self, event): if self.checkbox3D.isSelected(): self.updateSlice3D(self.imp) else: self.updateSlice2D(self.preview) def updateSlice3D(self, imp): selectedCell = self.cellList.selectedIndex selectedSlice = self.sliceList.selectedIndex if selectedCell >= 0 and selectedSlice >= 0 and imp is not None: cell = self.cells[selectedCell] impRoi = imp.getRoi() if cell is not None and impRoi is not None: index = selectedSlice + 1 roi = ShapeRoi(impRoi, position = index) cell.mode3D = True cell.name = "Cell %i (3D)" % cell.n cell.slices[selectedSlice].roi = roi if (index + 1 <= len(cell.slices)): imp.z = index + 1 self.cellList.repaint(self.cellList.getCellBounds(selectedCell, selectedCell)) self.sliceList.repaint(self.sliceList.getCellBounds(selectedSlice, selectedSlice)) def updateSlice2D(self, imp): selectedCell = self.cellList.selectedIndex if selectedCell >= 0 and imp is not None: cell = self.cells[selectedCell] impRoi = imp.getRoi() if cell is not None and impRoi is not None: roi = ShapeRoi(impRoi, position = 1) cell.mode3D = False cell.name = "Cell %i (2D)" % cell.n cell.roi = roi self.cellList.repaint(self.cellList.getCellBounds(selectedCell, selectedCell)) def imageOpened(self, imp): pass def imageClosed(self, imp): pass def imageUpdated(self, imp): if self.checkbox3D.isSelected(): if imp is not None: selectedCell = self.cellList.selectedIndex selectedSlice = imp.z - 1 if imp == self.imp and selectedSlice != self.sliceList.selectedIndex: self.sliceList.selectedIndex = selectedSlice def doneSelecting(self, event): oluts = self.imp.luts luts = [] channels = [] for c, method in enumerate(self.methods): if method != "None": luts.append(oluts[c]) channels.append(c) for cell in self.cells: manders = self.getManders(self.imp, cell) if manders is not None: chimps, thrimps, thrs, raws, thrds = manders index = self.cells.index(cell) + 1 title = "Cell_%i-" % index + self.imp.title self.saveMultichannelImage(title, chimps, oluts) title = "Cell_%i_thrd-" % index + self.imp.title self.saveMultichannelImage(title, thrimps, luts) self.results.incrementCounter() row = self.results.getCounter() - 1 for i, thr in enumerate(thrs): if thr is not None: self.results.setValue("Threshold %i" % (i + 1), row, int(thr)) for i, pair in enumerate(self.pairs): self.results.setValue("%i-%i M1 raw" % pair, row, float(raws[i].m1)) self.results.setValue("%i-%i M2 raw" % pair, row, float(raws[i].m2)) self.results.setValue("%i-%i M1 thrd" % pair, row, float(thrds[i].m1)) self.results.setValue("%i-%i M2 thrd" % pair, row, float(thrds[i].m2)) self.closeImage() if not self.processNextFile(): print "All done - happy analysis!" self.results.show("Manders collocalization results") self.exit() def windowClosing(self, e): print "Closing plugin - BYE!!!" self.exit() def exit(self): ImagePlus.removeImageListener(self) self.closeImage() self.closeMainWindow()
class ConfigTab(ITab, JPanel): def __init__(self, callbacks): self._callbacks = callbacks self._helpers = callbacks.getHelpers() self.__initLayout__() def __initLayout__(self): self._levelComboBox = JComboBox() levelComboBoxSize = Dimension(300, 30) self._levelComboBox.setPreferredSize(levelComboBoxSize) self._levelComboBox.setMaximumSize(levelComboBoxSize) for level in range(0, 6): self._levelComboBox.addItem(str(level)) self._techRenderedCheckBox = JCheckBox('Rendered', True) self._techTimebasedCheckBox = JCheckBox('Time-based', True) self._plugin_groups = {} for plugin in plugins: parent = plugin.__base__.__name__ if not self._plugin_groups.has_key(parent): self._plugin_groups[parent] = [] self._plugin_groups[parent].append(plugin) self._pluginCheckBoxes = [] for pluginGroup in self._plugin_groups.values(): for plugin in pluginGroup: self._pluginCheckBoxes.append(PluginCheckBox(plugin)) self._positionReplaceCheckBox = JCheckBox('Replace', True) self._positionAppendCheckBox = JCheckBox('Append', False) displayItems = ({ 'label': 'Level', 'components': (self._levelComboBox, ), 'description': 'Level of code context escape to perform (1-5, Default:0).' }, { 'label': 'Techniques', 'components': ( self._techRenderedCheckBox, self._techTimebasedCheckBox, ), 'description': 'Techniques R(endered) T(ime-based blind). Default: RT.' }, { 'label': 'Template Engines', 'components': self._pluginCheckBoxes, 'description': 'Force back-end template engine to this value(s).' }, { 'label': 'Payload position', 'components': ( self._positionReplaceCheckBox, self._positionAppendCheckBox, ), 'description': 'Scan payload position. This feature only appears in BurpExtension.' }) layout = GroupLayout(self) self.setLayout(layout) layout.setAutoCreateGaps(True) layout.setAutoCreateContainerGaps(True) labelWidth = 200 hgroup = layout.createParallelGroup(GroupLayout.Alignment.LEADING) vgroup = layout.createSequentialGroup() for displayItem in displayItems: label = JLabel(displayItem.get('label')) label.setToolTipText(displayItem.get('description')) _hgroup = layout.createSequentialGroup().addComponent( label, labelWidth, labelWidth, labelWidth) _vgroup = layout.createParallelGroup( GroupLayout.Alignment.BASELINE).addComponent(label) for component in displayItem.get('components'): _hgroup.addComponent(component) _vgroup.addComponent(component) hgroup.addGroup(_hgroup) vgroup.addGroup(_vgroup) layout.setHorizontalGroup(hgroup) layout.setVerticalGroup(vgroup) def getTabCaption(self): return 'Tplmap' def getUiComponent(self): return self def getLevel(self): return self._levelComboBox.getSelectedIndex() def getTechniques(self): return '%s%s' % ('R' if self._techRenderedCheckBox.isSelected( ) else '', 'T' if self._techTimebasedCheckBox.isSelected() else '') def getEngines(self): return [ checkbox.getPlugin() for checkbox in self._pluginCheckBoxes if checkbox.isSelected() ] def getPayloadPosition(self): return { 'replace': self._positionReplaceCheckBox.isSelected(), 'append': self._positionAppendCheckBox.isSelected() }
class BurpExtender(IBurpExtender, IBurpExtenderCallbacks, IIntruderPayloadProcessor, ITab, IExtensionStateListener): def registerExtenderCallbacks( self, callbacks): self._helpers = callbacks.getHelpers() callbacks.setExtensionName("JWT FuzzHelper") callbacks.registerIntruderPayloadProcessor(self) callbacks.registerExtensionStateListener(self) self._stdout = PrintWriter(callbacks.getStdout(), True) self._stderr = PrintWriter(callbacks.getStderr(), True) # Holds values passed by user from Configuration panel self._fuzzoptions = { "target" : "Header", "selector" : None, "signature" : False, "algorithm" : "HS256", "key" : "", "key_cmd" : "" } self._isNone = lambda val: isinstance(val, type(None)) # Configuration panel Layout self._configurationPanel = JPanel() gridBagLayout = GridBagLayout() gridBagLayout.columnWidths = [ 0, 0, 0] gridBagLayout.rowHeights = [ 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] gridBagLayout.columnWeights = [ 0.0, 0.0, 0.0 ] gridBagLayout.rowWeights = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0] self._configurationPanel.setLayout(gridBagLayout) # Setup tabs self._tabs = JTabbedPane() self._tabs.addTab('Configuration',self._configurationPanel) #self._tabs.addTab('Help',self._helpPanel) # Target Options targetLabel = JLabel("Target Selection (Required): ") targetLabel.setFont(Font("Tahoma",Font.BOLD, 12)) c = GridBagConstraints() c.gridx = 0 c.gridy = 1 c.insets = Insets(0,10,0,0) c.anchor = GridBagConstraints.LINE_END self._configurationPanel.add(targetLabel,c) options = [ 'Header', 'Payload' ] self._targetComboBox = JComboBox(options) c = GridBagConstraints() c.gridx = 1 c.gridy = 1 c.anchor = GridBagConstraints.LINE_START self._configurationPanel.add(self._targetComboBox,c) # Help Button self._helpButton = JButton("Help", actionPerformed=self.helpMenu) c = GridBagConstraints() c.gridx = 2 c.gridy = 1 c.anchor = GridBagConstraints.FIRST_LINE_START self._configurationPanel.add(self._helpButton,c) # Selector Options self._selectorLabel = JLabel("JSON Selector [Object Identifier-Index Syntax] (Required): ") self._selectorLabel.setFont(Font("Tahoma",Font.BOLD, 12)) c = GridBagConstraints() c.gridx = 0 c.gridy = 2 c.insets = Insets(0,10,0,0) c.anchor = GridBagConstraints.LINE_END self._configurationPanel.add(self._selectorLabel, c) self._selectorTextField = JTextField('',50) c = GridBagConstraints() c.gridx = 1 c.gridy = 2 self._configurationPanel.add(self._selectorTextField, c) # Regex option self._regexLabel = JLabel("Use regex as JSON Selector? (Optional): ") self._regexLabel.setFont(Font("Tahoma",Font.BOLD, 12)) c = GridBagConstraints() c.gridx = 0 c.gridy = 3 c.insets = Insets(0,0,0,0) c.anchor = GridBagConstraints.LINE_END self._configurationPanel.add(self._regexLabel,c) self._regexCheckBox = JCheckBox("", actionPerformed=self.regexSelector) c = GridBagConstraints() c.gridx = 1 c.gridy = 3 c.anchor = GridBagConstraints.FIRST_LINE_START self._configurationPanel.add(self._regexCheckBox,c) # Signature Options generateSignatureLabel = JLabel("Generate signature? (Required): ") generateSignatureLabel.setFont(Font("Tahoma",Font.BOLD, 12)) c = GridBagConstraints() c.gridx = 0 c.gridy = 4 c.insets = Insets(0,10,0,0) c.anchor = GridBagConstraints.LINE_END self._configurationPanel.add(generateSignatureLabel,c) options = ["False", "True"] self._generateSignatureComboBox = JComboBox(options) c = GridBagConstraints() c.gridx = 1 c.gridy = 4 c.anchor = GridBagConstraints.LINE_START self._configurationPanel.add(self._generateSignatureComboBox,c) signatureAlgorithmLabel = JLabel("Signature Algorithm (Optional): ") signatureAlgorithmLabel.setFont(Font("Tahoma",Font.BOLD, 12)) c = GridBagConstraints() c.gridx = 0 c.gridy = 5 c.insets = Insets(0,10,0,0) c.anchor = GridBagConstraints.LINE_END self._configurationPanel.add(signatureAlgorithmLabel,c) options = ["None", "HS256","HS384","HS512","ES256","ES384","ES512","RS256","RS384","RS512","PS256","PS256","PS384","PS512"] self._algorithmSelectionComboBox = JComboBox(options) c = GridBagConstraints() c.gridx = 1 c.gridy = 5 c.anchor = GridBagConstraints.LINE_START self._configurationPanel.add(self._algorithmSelectionComboBox,c) # Signing key options self._signingKeyLabel = JLabel("Signing Key (Optional): ") self._signingKeyLabel.setFont(Font("Tahoma",Font.BOLD, 12)) c = GridBagConstraints() c.gridx = 0 c.gridy = 6 c.insets = Insets(0,10,0,0) c.anchor = GridBagConstraints.LINE_END self._configurationPanel.add(self._signingKeyLabel,c) self.addSigningKeyTextArea() self._fromFileTextField = JTextField('',50) fromFileLabel = JLabel("Signing key from file? (Optional): ") fromFileLabel.setFont(Font("Tahoma",Font.BOLD, 12)) c = GridBagConstraints() c.gridx = 0 c.gridy = 7 c.insets = Insets(0,0,0,0) c.anchor = GridBagConstraints.LINE_END self._configurationPanel.add(fromFileLabel,c) self._fromFileCheckBox = JCheckBox("", actionPerformed=self.fromFile) c = GridBagConstraints() c.gridx = 1 c.gridy = 7 c.anchor = GridBagConstraints.FIRST_LINE_START self._configurationPanel.add(self._fromFileCheckBox,c) self._fromCmdTextField = JTextField('',50) fromCmdLabel = JLabel("Signing key from command? (Optional): ") fromCmdLabel.setFont(Font("Tahoma",Font.BOLD, 12)) c = GridBagConstraints() c.gridx = 0 c.gridy = 8 c.insets = Insets(0,0,0,0) c.anchor = GridBagConstraints.LINE_END self._configurationPanel.add(fromCmdLabel,c) self._fromCmdCheckBox = JCheckBox("", actionPerformed=self.fromCmd) c = GridBagConstraints() c.gridx = 1 c.gridy = 8 c.anchor = GridBagConstraints.FIRST_LINE_START self._configurationPanel.add(self._fromCmdCheckBox,c) self._saveButton = JButton("Save Configuration", actionPerformed=self.saveOptions) self._saveButton.setText("Save Configuration") c = GridBagConstraints() c.gridx = 1 c.gridy = 9 c.anchor = GridBagConstraints.FIRST_LINE_START self._configurationPanel.add(self._saveButton,c) callbacks.customizeUiComponent(self._configurationPanel) callbacks.customizeUiComponent(self._tabs) callbacks.addSuiteTab(self) self._stdout.println("[JWT FuzzHelper] Loaded successfully") return def getProcessorName(self): return "JWT Fuzzer" def extensionUnloaded(self): del self._configurationPanel return # Intruder logic function def processPayload(self, currentPayload, originalPayload, baseValue): dataParameter = self._helpers.bytesToString( self._helpers.urlDecode(baseValue) ) # utf-8 encode header,payload,signature = [unicode(s).encode('utf-8') for s in dataParameter.split(".",3)] decoded_header = self._helpers.bytesToString( self._helpers.base64Decode(header + "=" * (-len(header) % 4)) ) decoded_payload = self._helpers.bytesToString( self._helpers.base64Decode(payload+"=" * (-len(payload) % 4)) ) # Decode header and payload, preserving order if they are JSON objects # Decode header try: header_dict = json.loads(decoded_header, object_pairs_hook=OrderedDict) except ValueError: raise RuntimeException("[JWT FuzzHelper] Error: ValueError. Failed to decode header!") except Exception as e: self._stderr.println("[ERROR] Encountered an unknown error when decoding header:\n{}\nCarrying on...".format(e)) # Decode payload # Payload does not have to be a JSON object. # Ref: https://github.com/auth0/node-jsonwebtoken#usage payload_is_string = False try: payload_dict = json.loads(decoded_payload, object_pairs_hook=OrderedDict) except ValueError: payload_is_string = True payload_dict = decoded_payload except Exception as e: self._stderr.println("[ERROR] Encountered an unknown error when decoding payload:\n{}\nCarrying on...".format(e)) target = header_dict if self._fuzzoptions["target"] == "Header" else payload_dict selector = self._fuzzoptions["selector"] # If using Object Identifier-Index then retrieve the # value specified by the selector, # if this value does not exist, assume the user # wants to add the value that would have been specified # by the selector to the desired JWT segment (this behavior will # be noted in the help docs) intruderPayload = self._helpers.bytesToString(currentPayload) if not self._fuzzoptions["regex"]: if selector != [""]: try: value = self.getValue(target, selector) except Exception: target = self.buildDict(target, selector) if not self._isNone(selector) and selector != [""]: target = self.setValue(target, selector, intruderPayload) # Simple match-replace for regex if self._fuzzoptions["regex"]: target_string = target if payload_is_string else json.dumps(target) target_string = re.sub(selector, intruderPayload, target_string) target = target_string if payload_is_string else json.loads(target_string, object_pairs_hook=OrderedDict) if self._fuzzoptions["target"] == "Payload": payload_dict = target else: header_dict = target algorithm = self._fuzzoptions["algorithm"] if self._fuzzoptions["signature"]: # pyjwt requires lowercase 'none'. If user wants to try # "none", "NonE", "nOnE", etc... they should use .alg # as selector, delete sig from intruder and use those # permutations as their fuzz list (outlined in help docs) # and keep "Generate Signature" as False algorithm = "none" if algorithm.lower() == "none" else algorithm header_dict["alg"] = algorithm header = json.dumps(header_dict, separators=(",",":")) payload = payload_dict if payload_is_string else json.dumps(payload_dict, separators=(",",":")) header = self._helpers.base64Encode(header).strip("=") payload = self._helpers.base64Encode(payload).strip("=") contents = header + "." + payload key = self._fuzzoptions["key"] if len(self._fuzzoptions["key_cmd"]) > 0: # we provide 'contents' value as an only argument to key-generating command # it is expected that the command will print only the signature signature = check_output([self._fuzzoptions["key_cmd"], contents]) modified_jwt = contents + "." + signature elif self._fuzzoptions["signature"]: # pyjwt throws error when using a public key in symmetric alg (for good reason of course), # must do natively to support algorithmic sub attacks if algorithm.startswith("HS"): if algorithm == "HS256": hmac_algorithm = hashlib.sha256 elif algorithm == "HS384": hmac_algorithm = hashlib.sha384 else: hmac_algorithm = hashlib.sha512 signature = self._helpers.base64Encode( hmac.new( key, contents, hmac_algorithm ).digest() ).strip("=") modified_jwt = contents + "." +signature # JWT can't sign non-JSON payloads. WTF. This block is for non-JSON payloads. elif algorithm.startswith("RS") and payload_is_string: if algorithm == "RS256": rsa_algorithm = "SHA-256" elif algorithm == "RS384": rsa_algorithm = "SHA-384" else: rsa_algorithm = "SHA-512" privkey = rsa.PrivateKey.load_pkcs1(key) signature = rsa.sign(contents,privkey,rsa_algorithm) signature = base64.b64encode(signature).encode('utf-8').replace("=", "") modified_jwt = contents + "." + signature else: # Use pyjwt when using asymmetric alg if algorithm == "none": key = "" modified_jwt = jwt.encode(payload_dict,key,algorithm=algorithm,headers=header_dict) else: modified_jwt = contents + "." + signature return self._helpers.stringToBytes(modified_jwt) #----------------------- # getValue: # @return: A value at arbitrary depth in dictionary # @throws: TypeError #----------------------- def getValue(self, dictionary, values): return reduce(dict.__getitem__, values, dictionary) #----------------------- # buildDict: # @note: Will build dictionary of arbitrary depth #----------------------- def buildDict(self, dictionary, keys): if self._isNone(keys): return dictionary root = current = dictionary for key in keys: if key not in current: current[key] = {} current = current[key] return root #---------------------- # setValue: # @note: Will set key of arbitrary depth #----------------------- def setValue(self, dictionary, keys, value): root = current = dictionary for i,key in enumerate(keys): if i == len(keys) - 1: current[key] = value break if key in current: current = current[key] else: # Should never happen current = self.buildDict(current, keys) return root #----------------------- # addSigningKeyTextArea: # @note: Will toggle if fromFile selected. Be DRY. #---------------------- def addSigningKeyTextArea(self): self._signingKeyTextArea = JTextArea() self._signingKeyTextArea.setColumns(50) self._signingKeyTextArea.setRows(10) self._signingKeyScrollPane = JScrollPane(self._signingKeyTextArea) c = GridBagConstraints() c.gridx = 1 c.gridy = 6 c.anchor = GridBagConstraints.LINE_START self._configurationPanel.add(self._signingKeyScrollPane,c) def addSigningKeyFromFileTextField(self): c = GridBagConstraints() c.gridx = 1 c.gridy = 6 self._configurationPanel.add(self._fromFileTextField, c) def addSigningKeyFromCmdTextField(self): c = GridBagConstraints() c.gridx = 1 c.gridy = 6 self._configurationPanel.add(self._fromCmdTextField, c) #----------------------- # End Helpers #----------------------- #----------------------- # Implement ITab #----------------------- def getTabCaption(self): return "JWT FuzzHelper" def getUiComponent(self): return self._tabs #--------------------------- # Save configuration options #--------------------------- def saveOptions(self,event): self._fuzzoptions["target"] = self._targetComboBox.getSelectedItem() self._fuzzoptions["selector"] = self._selectorTextField.getText() self._fuzzoptions["signature"] = True if self._generateSignatureComboBox.getSelectedItem() == "True" else False self._fuzzoptions["algorithm"] = self._algorithmSelectionComboBox.getSelectedItem() self._fuzzoptions["key_cmd"] = "" if self._fromFileCheckBox.isSelected(): filename = self._fromFileTextField.getText() if os.path.isdir(filename): self._stderr.println("{} is a directory".format(filename)) return if os.path.exists(filename): with open(filename, 'rb') as f: self._fuzzoptions["key"] = f.read() elif self._fromCmdCheckBox.isSelected(): self._fuzzoptions["key_cmd"] = self._fromCmdTextField.getText() else: self._fuzzoptions["key"] = unicode(self._signingKeyTextArea.getText()).encode("utf-8") # RSA keys need to end with a line break. Many headaches because of this. if not self._fuzzoptions["key"].endswith("\n") and self._fuzzoptions["algorithm"].startswith("RS"): self._fuzzoptions["key"] += "\n" self._stdout.println("[JWT FuzzHelper] Saved options:\n{}".format(self._fuzzoptions)) # Sanity check selector if it's not a regular expression self._fuzzoptions["regex"] = self._regexCheckBox.isSelected() if not self._regexCheckBox.isSelected(): m = re.search("(\.\w+)+",self._fuzzoptions["selector"]) if self._fuzzoptions["selector"] != "." and (isinstance(m,type(None)) or m.group(0) != self._fuzzoptions["selector"]): self._saveButton.setText("Invalid JSON Selector!") else: self._fuzzoptions["selector"] = self._fuzzoptions["selector"].split(".")[1:] self._saveButton.setText("Saved!") # Sanity check the regular expression else: try: re.compile(self._fuzzoptions["selector"]) self._saveButton.setText("Saved!") except re.error: self._saveButton.setText("Invalid Regex!") return #------------------------- # From file options #------------------------ def fromFile(self,event): if self._fromFileCheckBox.isSelected(): self._signingKeyLabel.setText("Path to Signing Key (Optional): ") self._configurationPanel.remove(self._signingKeyScrollPane) self.addSigningKeyFromFileTextField() else: self._signingKeyLabel.setText("Signing Key (Optional): ") self._configurationPanel.remove(self._fromFileTextField) self.addSigningKeyTextArea() self._configurationPanel.repaint() return def fromCmd(self,event): if self._fromCmdCheckBox.isSelected(): self._signingKeyLabel.setText("Path to Signing Cmd (Optional): ") self._configurationPanel.remove(self._signingKeyScrollPane) self.addSigningKeyFromCmdTextField() else: self._signingKeyLabel.setText("Signing Key (Optional): ") self._configurationPanel.remove(self._fromCmdTextField) self.addSigningKeyTextArea() self._configurationPanel.repaint() return def regexSelector(self,event): if self._regexCheckBox.isSelected(): self._selectorLabel.setText("Selector [Regex] (Required): ") else: self._selectorLabel.setText("JSON Selector [Object Identifier-Index Syntax] (Required): ") self._configurationPanel.repaint() return #------------------------- # Help popup #------------------------- 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
class WelcomeView(JDialog): def __init__(self, controller): self.logger = logging.getLogger('NammuController') self.setAlwaysOnTop(False) self.controller = controller def display(self): ''' Displays window. ''' self.build() self.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) self.setResizable(False) self.setTitle('Welcome to Nammu') self.pack() self.setLocationRelativeTo(None) self.visible = 1 def build(self): ''' Adds the welcome panel to the JDialog window. ''' self.setLayout(BorderLayout()) self.add(self.build_welcome_panel(), BorderLayout.CENTER) def build_welcome_panel(self): ''' Construct the welcome panel here. ''' panel = JPanel(GridBagLayout()) constraints = GridBagConstraints() constraints.insets = Insets(10, 10, 10, 10) message = ('<html><body>' '<h1>Welcome to Nammu</h1>' '<h2>An editor for the ORACC project<h2>' '<p>' '<a href=\'oracc\'>Click here</a> for help with ORACC.' '</p>' '<p>Learn more about Nammu <a href=\'nammu\'>here</a>.</p>' '</body></html>') # Configure a JEditorPane to display HTML for our welcome message msg_pane = JEditorPane() msg_pane.setEditable(False) kit = HTMLEditorKit() msg_pane.setEditorKit(kit) scrollPane = JScrollPane(msg_pane) # This handles the stylesheet applied to the welcome message styleSheet = kit.getStyleSheet() styleSheet.addRule('body {color:black; font-size: 16 pt; }') styleSheet.addRule('h1 {text-align:center; }') styleSheet.addRule('h2 {text-align:center; }') # Set the JEditorPane background to match the rest of the window msg_pane.border = BorderFactory.createEmptyBorder(4, 4, 4, 4) msg_pane.background = Color(238, 238, 238) # Add the message and the css and to the JEditorPane doc = kit.createDefaultDocument() msg_pane.setDocument(doc) msg_pane.setText(message) # Set up a hyperlink listener listener = addEventListener(msg_pane, HyperlinkListener, 'hyperlinkUpdate', self.handleEvent) # Configure the placement of the JEditorPane constraints.gridx = 1 constraints.gridy = 1 constraints.fill = GridBagConstraints.BOTH constraints.anchor = GridBagConstraints.CENTER panel.add(msg_pane, constraints) # Build and place the checkbox self.checkbox = JCheckBox('Don\'t show this message again.', selected=False) constraints.gridx = 1 constraints.gridy = 2 panel.add(self.checkbox, constraints) # Build and place the close button close_button = JButton('Close', actionPerformed=self.close_action) constraints.gridx = 2 constraints.gridy = 2 panel.add(close_button, constraints) return panel def close_action(self, event): if self.checkbox.isSelected(): # Update settings.yaml self.controller.update_welcome_flag(False) # Close the welcome window self.dispose() def handleEvent(self, event): ''' A simple event handler for clicked hyperlinks, to direct to the documentation and the github repo. ''' if event.getEventType() is EventType.ACTIVATED: # Shorthand for NammuController nammu = self.controller.controller nammu._open_website(nammu.urls[event.getDescription()])