class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, IContextMenuFactory): def registerExtenderCallbacks(self, callbacks): # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("Autorize") # create the log and a lock on which to synchronize when adding log entries self._log = ArrayList() self._lock = Lock() self.intercept = 0 self.initInterceptionFilters() self.initEnforcementDetector() self.initExport() self.initConfigurationTab() self.initTabs() self.initCallbacks() print "Thank you for installing Autorize v0.9 extension" print "by Barak Tawily" return def initExport(self): # ## init enforcement detector tab # exportLType = JLabel("File Type:") exportLType.setBounds(10, 10, 100, 30) exportLES = JLabel("Enforcement Statuses:") exportLES.setBounds(10, 50, 160, 30) exportFileTypes = ["HTML"] self.exportType = JComboBox(exportFileTypes) self.exportType.setBounds(100, 10, 200, 30) exportES = [ "All Statuses", "Authorization bypass!", "Authorization enforced??? (please configure enforcement detector)", "Authorization enforced!" ] self.exportES = JComboBox(exportES) self.exportES.setBounds(100, 50, 200, 30) exportLES = JLabel("Statuses:") exportLES.setBounds(10, 50, 100, 30) self.exportButton = JButton("Export", actionPerformed=self.exportToHTML) self.exportButton.setBounds(390, 25, 100, 30) self.exportPnl = JPanel() self.exportPnl.setLayout(None) self.exportPnl.setBounds(0, 0, 1000, 1000) self.exportPnl.add(exportLType) self.exportPnl.add(self.exportType) self.exportPnl.add(exportLES) self.exportPnl.add(self.exportES) self.exportPnl.add(self.exportButton) def initEnforcementDetector(self): # ## init enforcement detector tab # self.EDFP = ArrayList() self.EDCT = ArrayList() EDLType = JLabel("Type:") EDLType.setBounds(10, 10, 140, 30) EDLContent = JLabel("Content:") EDLContent.setBounds(10, 50, 140, 30) EDLabelList = JLabel("Filter List:") EDLabelList.setBounds(10, 165, 140, 30) EDStrings = [ "Finger Print: (enforced message body contains)", "Content-Length: (constant Content-Length number of enforced response)" ] self.EDType = JComboBox(EDStrings) self.EDType.setBounds(80, 10, 430, 30) self.EDText = JTextArea("", 5, 30) self.EDText.setBounds(80, 50, 300, 110) self.EDModel = DefaultListModel() self.EDList = JList(self.EDModel) self.EDList.setBounds(80, 175, 300, 110) self.EDList.setBorder(LineBorder(Color.BLACK)) self.EDAdd = JButton("Add filter", actionPerformed=self.addEDFilter) self.EDAdd.setBounds(390, 85, 120, 30) self.EDDel = JButton("Remove filter", actionPerformed=self.delEDFilter) self.EDDel.setBounds(390, 210, 120, 30) self.EDPnl = JPanel() self.EDPnl.setLayout(None) self.EDPnl.setBounds(0, 0, 1000, 1000) self.EDPnl.add(EDLType) self.EDPnl.add(self.EDType) self.EDPnl.add(EDLContent) self.EDPnl.add(self.EDText) self.EDPnl.add(self.EDAdd) self.EDPnl.add(self.EDDel) self.EDPnl.add(EDLabelList) self.EDPnl.add(self.EDList) def initInterceptionFilters(self): # ## init interception filters tab # IFStrings = [ "URL Contains: ", "Scope items only: (Content is not required)" ] self.IFType = JComboBox(IFStrings) self.IFType.setBounds(80, 10, 430, 30) self.IFModel = DefaultListModel() self.IFList = JList(self.IFModel) self.IFList.setBounds(80, 175, 300, 110) self.IFList.setBorder(LineBorder(Color.BLACK)) self.IFText = JTextArea("", 5, 30) self.IFText.setBounds(80, 50, 300, 110) IFLType = JLabel("Type:") IFLType.setBounds(10, 10, 140, 30) IFLContent = JLabel("Content:") IFLContent.setBounds(10, 50, 140, 30) IFLabelList = JLabel("Filter List:") IFLabelList.setBounds(10, 165, 140, 30) self.IFAdd = JButton("Add filter", actionPerformed=self.addIFFilter) self.IFAdd.setBounds(390, 85, 120, 30) self.IFDel = JButton("Remove filter", actionPerformed=self.delIFFilter) self.IFDel.setBounds(390, 210, 120, 30) self.filtersPnl = JPanel() self.filtersPnl.setLayout(None) self.filtersPnl.setBounds(0, 0, 1000, 1000) self.filtersPnl.add(IFLType) self.filtersPnl.add(self.IFType) self.filtersPnl.add(IFLContent) self.filtersPnl.add(self.IFText) self.filtersPnl.add(self.IFAdd) self.filtersPnl.add(self.IFDel) self.filtersPnl.add(IFLabelList) self.filtersPnl.add(self.IFList) def initConfigurationTab(self): # ## init configuration tab # self.prevent304 = JCheckBox("Prevent 304 Not Modified status code") self.prevent304.setBounds(290, 25, 300, 30) self.ignore304 = JCheckBox("Ignore 304/204 status code responses") self.ignore304.setBounds(290, 5, 300, 30) self.ignore304.setSelected(True) self.autoScroll = JCheckBox("Auto Scroll") self.autoScroll.setBounds(290, 45, 140, 30) startLabel = JLabel("Authorization checks:") startLabel.setBounds(10, 10, 140, 30) self.startButton = JButton("Autorize is off", actionPerformed=self.startOrStop) self.startButton.setBounds(160, 10, 120, 30) self.startButton.setBackground(Color(255, 100, 91, 255)) self.clearButton = JButton("Clear List", actionPerformed=self.clearList) self.clearButton.setBounds(10, 40, 100, 30) self.replaceString = JTextArea("Cookie: Insert=injected; header=here;", 5, 30) self.replaceString.setWrapStyleWord(True) self.replaceString.setLineWrap(True) self.replaceString.setBounds(10, 80, 470, 180) self.filtersTabs = JTabbedPane() self.filtersTabs.addTab("Enforcement Detector", self.EDPnl) self.filtersTabs.addTab("Interception Filters", self.filtersPnl) self.filtersTabs.addTab("Export", self.exportPnl) self.filtersTabs.setBounds(0, 280, 2000, 700) self.pnl = JPanel() self.pnl.setBounds(0, 0, 1000, 1000) self.pnl.setLayout(None) self.pnl.add(self.startButton) self.pnl.add(self.clearButton) self.pnl.add(self.replaceString) self.pnl.add(startLabel) self.pnl.add(self.autoScroll) self.pnl.add(self.ignore304) self.pnl.add(self.prevent304) self.pnl.add(self.filtersTabs) def initTabs(self): # ## init autorize tabs # self.logTable = Table(self) self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._splitpane.setResizeWeight(1) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) self.scrollPane.getVerticalScrollBar().addAdjustmentListener( autoScrollListener(self)) copyURLitem = JMenuItem("Copy URL") copyURLitem.addActionListener(copySelectedURL(self)) self.menu = JPopupMenu("Popup") self.menu.add(copyURLitem) self.tabs = JTabbedPane() self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self._originalrequestViewer = self._callbacks.createMessageEditor( self, False) self._originalresponseViewer = self._callbacks.createMessageEditor( self, False) self.tabs.addTab("Modified Request", self._requestViewer.getComponent()) self.tabs.addTab("Modified Response", self._responseViewer.getComponent()) self.tabs.addTab("Original Request", self._originalrequestViewer.getComponent()) self.tabs.addTab("Original Response", self._originalresponseViewer.getComponent()) self.tabs.addTab("Configuration", self.pnl) self.tabs.setSelectedIndex(4) self._splitpane.setRightComponent(self.tabs) def initCallbacks(self): # ## init callbacks # # customize our UI components self._callbacks.customizeUiComponent(self._splitpane) self._callbacks.customizeUiComponent(self.logTable) self._callbacks.customizeUiComponent(self.scrollPane) self._callbacks.customizeUiComponent(self.tabs) self._callbacks.customizeUiComponent(self.filtersTabs) self._callbacks.registerContextMenuFactory(self) # add the custom tab to Burp's UI self._callbacks.addSuiteTab(self) # ## Events functions # def startOrStop(self, event): if self.startButton.getText() == "Autorize is off": self.startButton.setText("Autorize is on") self.startButton.setBackground(Color.GREEN) self.intercept = 1 self._callbacks.registerHttpListener(self) else: self.startButton.setText("Autorize is off") self.startButton.setBackground(Color(255, 100, 91, 255)) self.intercept = 0 self._callbacks.removeHttpListener(self) def addEDFilter(self, event): typeName = self.EDType.getSelectedItem().split(":")[0] self.EDModel.addElement(typeName + ": " + self.EDText.getText()) def delEDFilter(self, event): index = self.EDList.getSelectedIndex() if not index == -1: self.EDModel.remove(index) def addIFFilter(self, event): typeName = self.IFType.getSelectedItem().split(":")[0] self.IFModel.addElement(typeName + ": " + self.IFText.getText()) def delIFFilter(self, event): index = self.IFList.getSelectedIndex() if not index == -1: self.IFModel.remove(index) def clearList(self, event): self._lock.acquire() self._log = ArrayList() row = self._log.size() self.fireTableRowsInserted(row, row) self._lock.release() def exportToHTML(self, event): parentFrame = JFrame() fileChooser = JFileChooser() fileChooser.setSelectedFile(File("AutorizeReprort.html")) fileChooser.setDialogTitle("Save Autorize Report") userSelection = fileChooser.showSaveDialog(parentFrame) if userSelection == JFileChooser.APPROVE_OPTION: fileToSave = fileChooser.getSelectedFile() enforcementStatusFilter = self.exportES.getSelectedItem() htmlContent = """<html><title>Autorize Report by Barak Tawily</title> <style> .datagrid table { border-collapse: collapse; text-align: left; width: 100%; } .datagrid {font: normal 12px/150% Arial, Helvetica, sans-serif; background: #fff; overflow: hidden; border: 1px solid #006699; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .datagrid table td, .datagrid table th { padding: 3px 10px; } .datagrid table thead th {background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; color:#FFFFFF; font-size: 15px; font-weight: bold; border-left: 1px solid #0070A8; } .datagrid table thead th:first-child { border: none; }.datagrid table tbody td { color: #00496B; border-left: 1px solid #E1EEF4;font-size: 12px;font-weight: normal; }.datagrid table tbody .alt td { background: #E1EEF4; color: #00496B; }.datagrid table tbody td:first-child { border-left: none; }.datagrid table tbody tr:last-child td { border-bottom: none; }.datagrid table tfoot td div { border-top: 1px solid #006699;background: #E1EEF4;} .datagrid table tfoot td { padding: 0; font-size: 12px } .datagrid table tfoot td div{ padding: 2px; }.datagrid table tfoot td ul { margin: 0; padding:0; list-style: none; text-align: right; }.datagrid table tfoot li { display: inline; }.datagrid table tfoot li a { text-decoration: none; display: inline-block; padding: 2px 8px; margin: 1px;color: #FFFFFF;border: 1px solid #006699;-webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; }.datagrid table tfoot ul.active, .datagrid table tfoot ul a:hover { text-decoration: none;border-color: #006699; color: #FFFFFF; background: none; background-color:#00557F;}div.dhtmlx_window_active, div.dhx_modal_cover_dv { position: fixed !important; } table { width: 100%; table-layout: fixed; } td { border: 1px solid #35f; overflow: hidden; text-overflow: ellipsis; } td.a { width: 13%; white-space: nowrap; } td.b { width: 9%; word-wrap: break-word; } </style> <body> <h1>Autorize Report<h1> <div class="datagrid"><table> <thead><tr><th>URL</th><th>Authorization Enforcement Status</th></tr></thead> <tbody>""" for i in range(0, self._log.size()): color = "" if self._log.get( i )._enfocementStatus == "Authorization enforced??? (please configure enforcement detector)": color = "yellow" if self._log.get(i)._enfocementStatus == "Authorization bypass!": color = "red" if self._log.get(i)._enfocementStatus == "Authorization enforced!": color = "LawnGreen" if enforcementStatusFilter == "All Statuses": htmlContent += "<tr bgcolor=\"%s\"><td><a href=\"%s\">%s</a></td><td>%s</td></tr>" % ( color, self._log.get(i)._url, self._log.get(i)._url, self._log.get(i)._enfocementStatus) else: if enforcementStatusFilter == self._log.get( i)._enfocementStatus: htmlContent += "<tr bgcolor=\"%s\"><td><a href=\"%s\">%s</a></td><td>%s</td></tr>" % ( color, self._log.get(i)._url, self._log.get(i)._url, self._log.get(i)._enfocementStatus) htmlContent += "</tbody></table></div></body></html>" f = open(fileToSave.getAbsolutePath(), 'w') f.writelines(htmlContent) f.close() # # implement IContextMenuFactory # def createMenuItems(self, invocation): responses = invocation.getSelectedMessages() if responses > 0: ret = LinkedList() requestMenuItem = JMenuItem("Send request to Autorize") cookieMenuItem = JMenuItem("Send cookie to Autorize") requestMenuItem.addActionListener( handleMenuItems(self, responses[0], "request")) cookieMenuItem.addActionListener( handleMenuItems(self, responses[0], "cookie")) ret.add(requestMenuItem) ret.add(cookieMenuItem) return (ret) return null # # implement ITab # def getTabCaption(self): return "Autorize" def getUiComponent(self): return self._splitpane # # extend AbstractTableModel # def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 2 def getColumnName(self, columnIndex): if columnIndex == 0: return "URL" if columnIndex == 1: return "Authorization Enforcement Status" return "" def getValueAt(self, rowIndex, columnIndex): logEntry = self._log.get(rowIndex) if columnIndex == 0: return logEntry._url.toString() if columnIndex == 1: return logEntry._enfocementStatus return "" # # implement IMessageEditorController # this allows our request/response viewers to obtain details about the messages being displayed # def getHttpService(self): return self._currentlyDisplayedItem.getHttpService() def getRequest(self): return self._currentlyDisplayedItem.getRequest() def getResponse(self): return self._currentlyDisplayedItem.getResponse() # # implement IHttpListener # def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): if self.intercept == 1: if self.prevent304.isSelected(): if messageIsRequest: requestHeaders = list( self._helpers.analyzeRequest(messageInfo).getHeaders()) newHeaders = list() found = 0 for header in requestHeaders: if not "If-None-Match:" in header and not "If-Modified-Since:" in header: newHeaders.append(header) found = 1 if found == 1: requestInfo = self._helpers.analyzeRequest(messageInfo) bodyBytes = messageInfo.getRequest()[requestInfo. getBodyOffset():] bodyStr = self._helpers.bytesToString(bodyBytes) messageInfo.setRequest( self._helpers.buildHttpMessage( newHeaders, bodyStr)) if not messageIsRequest: if not self.replaceString.getText( ) in self._helpers.analyzeRequest(messageInfo).getHeaders(): if self.ignore304.isSelected(): firstHeader = self._helpers.analyzeResponse( messageInfo.getResponse()).getHeaders()[0] if "304" in firstHeader or "204" in firstHeader: return if self.IFList.getModel().getSize() == 0: self.checkAuthorization( messageInfo, self._helpers.analyzeResponse( messageInfo.getResponse()).getHeaders()) else: urlString = str( self._helpers.analyzeRequest(messageInfo).getUrl()) for i in range(0, self.IFList.getModel().getSize()): if self.IFList.getModel().getElementAt(i).split( ":")[0] == "Scope items only": currentURL = URL(urlString) if self._callbacks.isInScope(currentURL): self.checkAuthorization( messageInfo, self._helpers.analyzeResponse( messageInfo.getResponse()). getHeaders()) if self.IFList.getModel().getElementAt(i).split( ":")[0] == "URL Contains": if self.IFList.getModel().getElementAt( i)[14:] in urlString: self.checkAuthorization( messageInfo, self._helpers.analyzeResponse( messageInfo.getResponse()). getHeaders()) return def makeRequest(self, messageInfo, message): requestURL = self._helpers.analyzeRequest(messageInfo).getUrl() return self._callbacks.makeHttpRequest( self._helpers.buildHttpService( str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https"), message) def makeMessage(self, messageInfo, removeOrNot): requestInfo = self._helpers.analyzeRequest(messageInfo) headers = requestInfo.getHeaders() if removeOrNot: headers = list(headers) removeHeaders = ArrayList() removeHeaders.add(self.replaceString.getText() [0:self.replaceString.getText().index(":")]) for header in headers[:]: for removeHeader in removeHeaders: if removeHeader in header: headers.remove(header) headers.append(self.replaceString.getText()) msgBody = messageInfo.getRequest()[requestInfo.getBodyOffset():] return self._helpers.buildHttpMessage(headers, msgBody) def checkAuthorization(self, messageInfo, originalHeaders): message = self.makeMessage(messageInfo, True) requestResponse = self.makeRequest(messageInfo, message) analyzedResponse = self._helpers.analyzeResponse( requestResponse.getResponse()) oldStatusCode = originalHeaders[0] newStatusCode = analyzedResponse.getHeaders()[0] oldContentLen = self.getContentLength(originalHeaders) newContentLen = self.getContentLength(analyzedResponse.getHeaders()) impression = "" EDFilters = self.EDModel.toArray() if oldStatusCode == newStatusCode: if oldContentLen == newContentLen: impression = "Authorization bypass!" else: impression = "Authorization enforced??? (please configure enforcement detector)" for filter in EDFilters: if str(filter).startswith("Content-Length: "): if newContentLen == filter: impression = "Authorization enforced!" if str(filter).startswith("Finger Print: "): if filter[14:] in self._helpers.bytesToString( requestResponse.getResponse() [analyzedResponse.getBodyOffset():]): impression = "Authorization enforced!" else: impression = "Authorization enforced!" self._lock.acquire() row = self._log.size() self._log.add( LogEntry(self._callbacks.saveBuffersToTempFiles(requestResponse), self._helpers.analyzeRequest(requestResponse).getUrl(), messageInfo, impression)) # same requests not include again. self.fireTableRowsInserted(row, row) self._lock.release() def getContentLength(self, analyzedResponseHeaders): for header in analyzedResponseHeaders: if "Content-Length:" in header: return header return "null" def getCookieFromMessage(self, messageInfo): headers = list( self._helpers.analyzeRequest( messageInfo.getRequest()).getHeaders()) for header in headers: if "Cookie:" in header: return header return None
def 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
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, IContextMenuFactory): # # implement IBurpExtender # def registerExtenderCallbacks(self, callbacks): # PDB debugging: connect sys.stdout and sys.stderr to Burp # 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 extension name callbacks.setExtensionName("To Do") # create the log and a lock on which to synchronize when adding # log entries self._log = ArrayList() self._lock = Lock() # main split pane self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) # Configuration Tab self.initConfigTab() # table of to do entries logTable = Table(self) scrollPane = JScrollPane(logTable) self._splitpane.setLeftComponent(scrollPane) # Config tab self.tabs = JTabbedPane() self._configuration = self._callbacks.createMessageEditor(self, False) self.tabs.addTab("Configuration", self._configuration.getComponent()) self._splitpane.setRightComponent(self.panel) # customize our UI components callbacks.customizeUiComponent(self._splitpane) callbacks.customizeUiComponent(logTable) callbacks.customizeUiComponent(scrollPane) # add the custom tab to Burp's UI callbacks.addSuiteTab(self) # register ourselves as an HTTP listener callbacks.registerHttpListener(self) # initialize tabs self.initTabs() # Print thank you, contact info, etc print("Thank you for installing Burp To Do List") print("created by Chris Lockard") print("https://github.com/chrislockard/BurpToDoList") return # # implement ITab # def getTabCaption(self): return "To Do" def getUiComponent(self): return self._splitpane def initConfigTab(self): # Init configuration tab self.test = JLabel("Configuration") self.test.setBounds(10, 10, 140, 30) self.panel = JPanel() self.panel.setBounds(0, 0, 1000, 1000) self.panel.setLayout(None) self.panel.add(self.test) def initTabs(self): # Init ToDo List Tabs self.logTable = Table(self) tableWidth = self.logTable.getPreferredSize().width self.logTable.getColumn("Complete?").setPreferredWidth( Math.round(tableWidth / 10 * 1)) self.logTable.getColumn("Section").setPreferredWidth( Math.round(tableWidth / 10 * 3)) self.logTable.getColumn("Task").setPreferredWidth( Math.round(tableWidth / 10 * 3)) self.logTable.getColumn("Notes").setPreferredWidth( Math.round(tableWidth / 10 * 3)) self.tableSorter = TableRowSorter(self) self.logTable.setRowSorter(self.tableSorter) 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)) def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 4 def getColumnName(self, columnIndex): if columnIndex == 0: return "Complete?" if columnIndex == 1: return "Section" if columnIndex == 2: return "Task" if columnIndex == 3: return "Notes" return "" def getColumnClass(self, columnIndex): if columnIndex == 0: return checkbox if columnIndex == 1: return String if columnIndex == 2: return String if columnIndex == 3: return String 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() if columnIndex == 2: pass if columnIndex == 3: pass return ""
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, IContextMenuFactory): def registerExtenderCallbacks(self, callbacks): # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("Autorize") # create the log and a lock on which to synchronize when adding log entries self._log = ArrayList() self._lock = Lock() self._enfocementStatuses = ["Authorization bypass!","Authorization enforced??? (please configure enforcement detector)","Authorization enforced!"] self.intercept = 0 self.initInterceptionFilters() self.initEnforcementDetector() self.initEnforcementDetectorUnauthorized() self.initExport() self.initConfigurationTab() self.initTabs() self.initCallbacks() self.currentRequestNumber = 1 print "Thank you for installing Autorize v0.12 extension" print "Created by Barak Tawily" print "Contributors: Barak Tawily, Federico Dotta" print "\nGithub:\nhttps://github.com/Quitten/Autorize" return def initExport(self): # ## init enforcement detector tab # exportLType = JLabel("File Type:") exportLType.setBounds(10, 10, 100, 30) exportLES = JLabel("Enforcement Statuses:") exportLES.setBounds(10, 50, 160, 30) exportFileTypes = ["HTML","CSV"] self.exportType = JComboBox(exportFileTypes) self.exportType.setBounds(100, 10, 200, 30) exportES = ["All Statuses", self._enfocementStatuses[0], self._enfocementStatuses[1], self._enfocementStatuses[2]] self.exportES = JComboBox(exportES) self.exportES.setBounds(100, 50, 200, 30) exportLES = JLabel("Statuses:") exportLES.setBounds(10, 50, 100, 30) self.exportButton = JButton("Export",actionPerformed=self.export) self.exportButton.setBounds(390, 25, 100, 30) self.exportPnl = JPanel() self.exportPnl.setLayout(None); self.exportPnl.setBounds(0, 0, 1000, 1000); self.exportPnl.add(exportLType) self.exportPnl.add(self.exportType) self.exportPnl.add(exportLES) self.exportPnl.add(self.exportES) self.exportPnl.add(self.exportButton) def initEnforcementDetector(self): # ## init enforcement detector tab # # These two variable appears to be unused... self.EDFP = ArrayList() self.EDCT = ArrayList() EDLType = JLabel("Type:") EDLType.setBounds(10, 10, 140, 30) EDLContent = JLabel("Content:") EDLContent.setBounds(10, 50, 140, 30) EDLabelList = JLabel("Filter List:") EDLabelList.setBounds(10, 165, 140, 30) EDStrings = ["Headers (simple string): (enforced message headers contains)", "Headers (regex): (enforced messege headers contains)", "Body (simple string): (enforced messege body contains)", "Body (regex): (enforced messege body contains)", "Full request (simple string): (enforced messege contains)", "Full request (regex): (enforced messege contains)", "Content-Length: (constant Content-Length number of enforced response)"] self.EDType = JComboBox(EDStrings) self.EDType.setBounds(80, 10, 430, 30) self.EDText = JTextArea("", 5, 30) self.EDText.setBounds(80, 50, 300, 110) self.EDModel = DefaultListModel(); self.EDList = JList(self.EDModel); self.EDList.setBounds(80, 175, 300, 110) self.EDList.setBorder(LineBorder(Color.BLACK)) self.EDAdd = JButton("Add filter",actionPerformed=self.addEDFilter) self.EDAdd.setBounds(390, 85, 120, 30) self.EDDel = JButton("Remove filter",actionPerformed=self.delEDFilter) self.EDDel.setBounds(390, 210, 120, 30) self.EDPnl = JPanel() self.EDPnl.setLayout(None); self.EDPnl.setBounds(0, 0, 1000, 1000); self.EDPnl.add(EDLType) self.EDPnl.add(self.EDType) self.EDPnl.add(EDLContent) self.EDPnl.add(self.EDText) self.EDPnl.add(self.EDAdd) self.EDPnl.add(self.EDDel) self.EDPnl.add(EDLabelList) self.EDPnl.add(self.EDList) def initEnforcementDetectorUnauthorized(self): # ## init enforcement detector tab # EDLType = JLabel("Type:") EDLType.setBounds(10, 10, 140, 30) EDLContent = JLabel("Content:") EDLContent.setBounds(10, 50, 140, 30) EDLabelList = JLabel("Filter List:") EDLabelList.setBounds(10, 165, 140, 30) EDStrings = ["Headers (simple string): (enforced message headers contains)", "Headers (regex): (enforced messege headers contains)", "Body (simple string): (enforced messege body contains)", "Body (regex): (enforced messege body contains)", "Full request (simple string): (enforced messege contains)", "Full request (regex): (enforced messege contains)", "Content-Length: (constant Content-Length number of enforced response)"] self.EDTypeUnauth = JComboBox(EDStrings) self.EDTypeUnauth.setBounds(80, 10, 430, 30) self.EDTextUnauth = JTextArea("", 5, 30) self.EDTextUnauth.setBounds(80, 50, 300, 110) self.EDModelUnauth = DefaultListModel(); self.EDListUnauth = JList(self.EDModelUnauth); self.EDListUnauth.setBounds(80, 175, 300, 110) self.EDListUnauth.setBorder(LineBorder(Color.BLACK)) self.EDAddUnauth = JButton("Add filter",actionPerformed=self.addEDFilterUnauth) self.EDAddUnauth.setBounds(390, 85, 120, 30) self.EDDelUnauth = JButton("Remove filter",actionPerformed=self.delEDFilterUnauth) self.EDDelUnauth.setBounds(390, 210, 120, 30) self.EDPnlUnauth = JPanel() self.EDPnlUnauth.setLayout(None); self.EDPnlUnauth.setBounds(0, 0, 1000, 1000); self.EDPnlUnauth.add(EDLType) self.EDPnlUnauth.add(self.EDTypeUnauth) self.EDPnlUnauth.add(EDLContent) self.EDPnlUnauth.add(self.EDTextUnauth) self.EDPnlUnauth.add(self.EDAddUnauth) self.EDPnlUnauth.add(self.EDDelUnauth) self.EDPnlUnauth.add(EDLabelList) self.EDPnlUnauth.add(self.EDListUnauth) def initInterceptionFilters(self): # ## init interception filters tab # IFStrings = ["Scope items only: (Content is not required)","URL Contains (simple string): ","URL Contains (regex): ","URL Not Contains (simple string): ","URL Not Contains (regex): "] self.IFType = JComboBox(IFStrings) self.IFType.setBounds(80, 10, 430, 30) self.IFModel = DefaultListModel(); self.IFList = JList(self.IFModel); self.IFList.setBounds(80, 175, 300, 110) self.IFList.setBorder(LineBorder(Color.BLACK)) self.IFText = JTextArea("", 5, 30) self.IFText.setBounds(80, 50, 300, 110) IFLType = JLabel("Type:") IFLType.setBounds(10, 10, 140, 30) IFLContent = JLabel("Content:") IFLContent.setBounds(10, 50, 140, 30) IFLabelList = JLabel("Filter List:") IFLabelList.setBounds(10, 165, 140, 30) self.IFAdd = JButton("Add filter",actionPerformed=self.addIFFilter) self.IFAdd.setBounds(390, 85, 120, 30) self.IFDel = JButton("Remove filter",actionPerformed=self.delIFFilter) self.IFDel.setBounds(390, 210, 120, 30) self.filtersPnl = JPanel() self.filtersPnl.setLayout(None); self.filtersPnl.setBounds(0, 0, 1000, 1000); self.filtersPnl.add(IFLType) self.filtersPnl.add(self.IFType) self.filtersPnl.add(IFLContent) self.filtersPnl.add(self.IFText) self.filtersPnl.add(self.IFAdd) self.filtersPnl.add(self.IFDel) self.filtersPnl.add(IFLabelList) self.filtersPnl.add(self.IFList) def initConfigurationTab(self): # ## init configuration tab # self.prevent304 = JCheckBox("Prevent 304 Not Modified status code") self.prevent304.setBounds(290, 25, 300, 30) self.ignore304 = JCheckBox("Ignore 304/204 status code responses") self.ignore304.setBounds(290, 5, 300, 30) self.ignore304.setSelected(True) self.autoScroll = JCheckBox("Auto Scroll") #self.autoScroll.setBounds(290, 45, 140, 30) self.autoScroll.setBounds(160, 40, 140, 30) self.doUnauthorizedRequest = JCheckBox("Check unauthenticated") self.doUnauthorizedRequest.setBounds(290, 45, 300, 30) self.doUnauthorizedRequest.setSelected(True) startLabel = JLabel("Authorization checks:") startLabel.setBounds(10, 10, 140, 30) self.startButton = JButton("Autorize is off",actionPerformed=self.startOrStop) self.startButton.setBounds(160, 10, 120, 30) self.startButton.setBackground(Color(255, 100, 91, 255)) self.clearButton = JButton("Clear List",actionPerformed=self.clearList) self.clearButton.setBounds(10, 40, 100, 30) self.replaceString = JTextArea("Cookie: Insert=injected; header=here;", 5, 30) self.replaceString.setWrapStyleWord(True); self.replaceString.setLineWrap(True) self.replaceString.setBounds(10, 80, 470, 180) self.filtersTabs = JTabbedPane() self.filtersTabs.addTab("Enforcement Detector", self.EDPnl) self.filtersTabs.addTab("Detector Unauthenticated", self.EDPnlUnauth) self.filtersTabs.addTab("Interception Filters", self.filtersPnl) self.filtersTabs.addTab("Export", self.exportPnl) self.filtersTabs.setBounds(0, 280, 2000, 700) self.pnl = JPanel() self.pnl.setBounds(0, 0, 1000, 1000); self.pnl.setLayout(None); self.pnl.add(self.startButton) self.pnl.add(self.clearButton) self.pnl.add(self.replaceString) self.pnl.add(startLabel) self.pnl.add(self.autoScroll) self.pnl.add(self.ignore304) self.pnl.add(self.prevent304) self.pnl.add(self.doUnauthorizedRequest) self.pnl.add(self.filtersTabs) def initTabs(self): # ## init autorize tabs # self.logTable = Table(self) self.logTable.setAutoCreateRowSorter(True) tableWidth = self.logTable.getPreferredSize().width self.logTable.getColumn("ID").setPreferredWidth(Math.round(tableWidth / 50 * 2)) self.logTable.getColumn("URL").setPreferredWidth(Math.round(tableWidth / 50 * 24)) self.logTable.getColumn("Orig. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Modif. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Unauth. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Authorization Enforcement Status").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Authorization Unauth. Status").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._splitpane.setResizeWeight(1) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) self.scrollPane.getVerticalScrollBar().addAdjustmentListener(autoScrollListener(self)) self.menuES0 = JCheckBoxMenuItem(self._enfocementStatuses[0],True) self.menuES1 = JCheckBoxMenuItem(self._enfocementStatuses[1],True) self.menuES2 = JCheckBoxMenuItem(self._enfocementStatuses[2],True) self.menuES0.addItemListener(menuTableFilter(self)) self.menuES1.addItemListener(menuTableFilter(self)) self.menuES2.addItemListener(menuTableFilter(self)) copyURLitem = JMenuItem("Copy URL"); copyURLitem.addActionListener(copySelectedURL(self)) self.menu = JPopupMenu("Popup") self.menu.add(copyURLitem) self.menu.add(self.menuES0) self.menu.add(self.menuES1) self.menu.add(self.menuES2) self.tabs = JTabbedPane() self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self._originalrequestViewer = self._callbacks.createMessageEditor(self, False) self._originalresponseViewer = self._callbacks.createMessageEditor(self, False) self._unauthorizedrequestViewer = self._callbacks.createMessageEditor(self, False) self._unauthorizedresponseViewer = self._callbacks.createMessageEditor(self, False) self.tabs.addTab("Modified Request", self._requestViewer.getComponent()) self.tabs.addTab("Modified Response", self._responseViewer.getComponent()) self.tabs.addTab("Original Request", self._originalrequestViewer.getComponent()) self.tabs.addTab("Original Response", self._originalresponseViewer.getComponent()) self.tabs.addTab("Unauthenticated Request", self._unauthorizedrequestViewer.getComponent()) self.tabs.addTab("Unauthenticated Response", self._unauthorizedresponseViewer.getComponent()) self.tabs.addTab("Configuration", self.pnl) self.tabs.setSelectedIndex(6) self._splitpane.setRightComponent(self.tabs) def initCallbacks(self): # ## init callbacks # # customize our UI components self._callbacks.customizeUiComponent(self._splitpane) self._callbacks.customizeUiComponent(self.logTable) self._callbacks.customizeUiComponent(self.scrollPane) self._callbacks.customizeUiComponent(self.tabs) self._callbacks.customizeUiComponent(self.filtersTabs) self._callbacks.registerContextMenuFactory(self) # add the custom tab to Burp's UI self._callbacks.addSuiteTab(self) # ## Events functions # def startOrStop(self, event): if self.startButton.getText() == "Autorize is off": self.startButton.setText("Autorize is on") self.startButton.setBackground(Color.GREEN) self.intercept = 1 self._callbacks.registerHttpListener(self) else: self.startButton.setText("Autorize is off") self.startButton.setBackground(Color(255, 100, 91, 255)) self.intercept = 0 self._callbacks.removeHttpListener(self) def addEDFilter(self, event): typeName = self.EDType.getSelectedItem().split(":")[0] self.EDModel.addElement(typeName + ": " + self.EDText.getText()) def delEDFilter(self, event): index = self.EDList.getSelectedIndex(); if not index == -1: self.EDModel.remove(index); def addEDFilterUnauth(self, event): typeName = self.EDTypeUnauth.getSelectedItem().split(":")[0] self.EDModelUnauth.addElement(typeName + ": " + self.EDTextUnauth.getText()) def delEDFilterUnauth(self, event): index = self.EDListUnauth.getSelectedIndex(); if not index == -1: self.EDModelUnauth.remove(index); def addIFFilter(self, event): typeName = self.IFType.getSelectedItem().split(":")[0] self.IFModel.addElement(typeName + ": " + self.IFText.getText()) def delIFFilter(self, event): index = self.IFList.getSelectedIndex(); if not index == -1: self.IFModel.remove(index); def clearList(self, event): self._lock.acquire() oldSize = self._log.size() self._log.clear() self.fireTableRowsDeleted(0, oldSize - 1) self._lock.release() def export(self, event): if self.exportType.getSelectedItem() == "HTML": self.exportToHTML() else: self.exportToCSV() def exportToCSV(self): parentFrame = JFrame() fileChooser = JFileChooser() fileChooser.setSelectedFile(File("AutorizeReprort.csv")); fileChooser.setDialogTitle("Save Autorize Report") userSelection = fileChooser.showSaveDialog(parentFrame) if userSelection == JFileChooser.APPROVE_OPTION: fileToSave = fileChooser.getSelectedFile() enforcementStatusFilter = self.exportES.getSelectedItem() csvContent = "id\tURL\tOriginal length\tModified length\tUnauthorized length\tAuthorization Enforcement Status\tAuthorization Unauthenticated Status\n" for i in range(0,self._log.size()): if enforcementStatusFilter == "All Statuses": csvContent += "%d\t%s\t%d\t%d\t%d\t%s\t%s\n" % (self._log.get(i)._id,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, self._log.get(i)._enfocementStatus, self._log.get(i)._enfocementStatusUnauthorized) else: if (enforcementStatusFilter == self._log.get(i)._enfocementStatus) or (enforcementStatusFilter == self._log.get(i)._enfocementStatusUnauthorized): csvContent += "%d\t%s\t%d\t%d\t%d\t%s\t%s\n" % (self._log.get(i)._id,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, self._log.get(i)._enfocementStatus, self._log.get(i)._enfocementStatusUnauthorized) f = open(fileToSave.getAbsolutePath(), 'w') f.writelines(csvContent) f.close() def exportToHTML(self): parentFrame = JFrame() fileChooser = JFileChooser() fileChooser.setSelectedFile(File("AutorizeReprort.html")); fileChooser.setDialogTitle("Save Autorize Report") userSelection = fileChooser.showSaveDialog(parentFrame) if userSelection == JFileChooser.APPROVE_OPTION: fileToSave = fileChooser.getSelectedFile() enforcementStatusFilter = self.exportES.getSelectedItem() htmlContent = """<html><title>Autorize Report by Barak Tawily</title> <style> .datagrid table { border-collapse: collapse; text-align: left; width: 100%; } .datagrid {font: normal 12px/150% Arial, Helvetica, sans-serif; background: #fff; overflow: hidden; border: 1px solid #006699; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .datagrid table td, .datagrid table th { padding: 3px 10px; } .datagrid table thead th {background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; color:#FFFFFF; font-size: 15px; font-weight: bold; border-left: 1px solid #0070A8; } .datagrid table thead th:first-child { border: none; }.datagrid table tbody td { color: #00496B; border-left: 1px solid #E1EEF4;font-size: 12px;font-weight: normal; }.datagrid table tbody .alt td { background: #E1EEF4; color: #00496B; }.datagrid table tbody td:first-child { border-left: none; }.datagrid table tbody tr:last-child td { border-bottom: none; }.datagrid table tfoot td div { border-top: 1px solid #006699;background: #E1EEF4;} .datagrid table tfoot td { padding: 0; font-size: 12px } .datagrid table tfoot td div{ padding: 2px; }.datagrid table tfoot td ul { margin: 0; padding:0; list-style: none; text-align: right; }.datagrid table tfoot li { display: inline; }.datagrid table tfoot li a { text-decoration: none; display: inline-block; padding: 2px 8px; margin: 1px;color: #FFFFFF;border: 1px solid #006699;-webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; }.datagrid table tfoot ul.active, .datagrid table tfoot ul a:hover { text-decoration: none;border-color: #006699; color: #FFFFFF; background: none; background-color:#00557F;}div.dhtmlx_window_active, div.dhx_modal_cover_dv { position: fixed !important; } table { width: 100%; table-layout: fixed; } td { border: 1px solid #35f; overflow: hidden; text-overflow: ellipsis; } td.a { width: 13%; white-space: nowrap; } td.b { width: 9%; word-wrap: break-word; } </style> <body> <h1>Autorize Report<h1> <div class="datagrid"><table> <thead><tr><th width=\"3%\">ID</th><th width=\"48%\">URL</th><th width=\"9%\">Original length</th><th width=\"9%\">Modified length</th><th width=\"9%\">Unauthorized length</th><th width=\"11%\">Authorization Enforcement Status</th><th width=\"11%\">Authorization Unauthenticated Status</th></tr></thead> <tbody>""" for i in range(0,self._log.size()): color_modified = "" if self._log.get(i)._enfocementStatus == self._enfocementStatuses[0]: color_modified = "red" if self._log.get(i)._enfocementStatus == self._enfocementStatuses[1]: color_modified = "yellow" if self._log.get(i)._enfocementStatus == self._enfocementStatuses[2]: color_modified = "LawnGreen" color_unauthorized = "" if self._log.get(i)._enfocementStatusUnauthorized == self._enfocementStatuses[0]: color_unauthorized = "red" if self._log.get(i)._enfocementStatusUnauthorized == self._enfocementStatuses[1]: color_unauthorized = "yellow" if self._log.get(i)._enfocementStatusUnauthorized == self._enfocementStatuses[2]: color_unauthorized = "LawnGreen" if enforcementStatusFilter == "All Statuses": htmlContent += "<tr><td>%d</td><td><a href=\"%s\">%s</a></td><td>%d</td><td>%d</td><td>%d</td><td bgcolor=\"%s\">%s</td><td bgcolor=\"%s\">%s</td></tr>" % (self._log.get(i)._id,self._log.get(i)._url,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, color_modified, self._log.get(i)._enfocementStatus, color_unauthorized, self._log.get(i)._enfocementStatusUnauthorized) else: if (enforcementStatusFilter == self._log.get(i)._enfocementStatus) or (enforcementStatusFilter == self._log.get(i)._enfocementStatusUnauthorized): htmlContent += "<tr><td>%d</td><td><a href=\"%s\">%s</a></td><td>%d</td><td>%d</td><td>%d</td><td bgcolor=\"%s\">%s</td><td bgcolor=\"%s\">%s</td></tr>" % (self._log.get(i)._id,self._log.get(i)._url,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, color_modified, self._log.get(i)._enfocementStatus, color_unauthorized, self._log.get(i)._enfocementStatusUnauthorized) htmlContent += "</tbody></table></div></body></html>" f = open(fileToSave.getAbsolutePath(), 'w') f.writelines(htmlContent) f.close() # # implement IContextMenuFactory # def createMenuItems(self, invocation): responses = invocation.getSelectedMessages(); if responses > 0: ret = LinkedList() requestMenuItem = JMenuItem("Send request to Autorize"); cookieMenuItem = JMenuItem("Send cookie to Autorize"); requestMenuItem.addActionListener(handleMenuItems(self,responses[0], "request")) cookieMenuItem.addActionListener(handleMenuItems(self, responses[0], "cookie")) ret.add(requestMenuItem); ret.add(cookieMenuItem); return(ret); return null; # # implement ITab # def getTabCaption(self): return "Autorize" def getUiComponent(self): return self._splitpane # # extend AbstractTableModel # def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 7 def getColumnName(self, columnIndex): if columnIndex == 0: return "ID" if columnIndex == 1: return "URL" if columnIndex == 2: return "Orig. Length" if columnIndex == 3: return "Modif. Length" if columnIndex == 4: return "Unauth. Length" if columnIndex == 5: return "Authorization Enforcement Status" if columnIndex == 6: return "Authorization Unauth. Status" return "" def getColumnClass(self, columnIndex): if columnIndex == 0: return Integer if columnIndex == 1: return String if columnIndex == 2: return Integer if columnIndex == 3: return Integer if columnIndex == 4: return Integer if columnIndex == 5: return String if columnIndex == 6: return String return String def getValueAt(self, rowIndex, columnIndex): logEntry = self._log.get(rowIndex) if columnIndex == 0: return logEntry._id if columnIndex == 1: return logEntry._url.toString() if columnIndex == 2: return len(logEntry._originalrequestResponse.getResponse()) if columnIndex == 3: return len(logEntry._requestResponse.getResponse()) if columnIndex == 4: if logEntry._unauthorizedRequestResponse != None: return len(logEntry._unauthorizedRequestResponse.getResponse()) else: #return "-" return 0 if columnIndex == 5: return logEntry._enfocementStatus if columnIndex == 6: return logEntry._enfocementStatusUnauthorized return "" # # implement IMessageEditorController # this allows our request/response viewers to obtain details about the messages being displayed # def getHttpService(self): return self._currentlyDisplayedItem.getHttpService() def getRequest(self): return self._currentlyDisplayedItem.getRequest() def getResponse(self): return self._currentlyDisplayedItem.getResponse() # # implement IHttpListener # def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): #if (self.intercept == 1) and (toolFlag != self._callbacks.TOOL_EXTENDER): if (self.intercept == 1) and (toolFlag == self._callbacks.TOOL_PROXY): if self.prevent304.isSelected(): if messageIsRequest: requestHeaders = list(self._helpers.analyzeRequest(messageInfo).getHeaders()) newHeaders = list() found = 0 for header in requestHeaders: if not "If-None-Match:" in header and not "If-Modified-Since:" in header: newHeaders.append(header) found = 1 if found == 1: requestInfo = self._helpers.analyzeRequest(messageInfo) bodyBytes = messageInfo.getRequest()[requestInfo.getBodyOffset():] bodyStr = self._helpers.bytesToString(bodyBytes) messageInfo.setRequest(self._helpers.buildHttpMessage(newHeaders, bodyStr)) if not messageIsRequest: if not self.replaceString.getText() in self._helpers.analyzeRequest(messageInfo).getHeaders(): if self.ignore304.isSelected(): firstHeader = self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders()[0] if "304" in firstHeader or "204" in firstHeader: return if self.IFList.getModel().getSize() == 0: self.checkAuthorization(messageInfo,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected()) else: urlString = str(self._helpers.analyzeRequest(messageInfo).getUrl()) do_the_check = 1 for i in range(0,self.IFList.getModel().getSize()): if self.IFList.getModel().getElementAt(i).split(":")[0] == "Scope items only": currentURL = URL(urlString) if not self._callbacks.isInScope(currentURL): do_the_check = 0 if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Contains (simple string)": if self.IFList.getModel().getElementAt(i)[30:] not in urlString: do_the_check = 0 if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Contains (regex)": regex_string = self.IFList.getModel().getElementAt(i)[22:] p = re.compile(regex_string, re.IGNORECASE) if not p.search(urlString): do_the_check = 0 if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Not Contains (simple string)": if self.IFList.getModel().getElementAt(i)[34:] in urlString: do_the_check = 0 if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Not Contains (regex)": regex_string = self.IFList.getModel().getElementAt(i)[26:] p = re.compile(regex_string, re.IGNORECASE) if p.search(urlString): do_the_check = 0 if do_the_check: self.checkAuthorization(messageInfo,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected()) return def sendRequestToAutorizeWork(self,messageInfo): if messageInfo.getResponse() == None: message = self.makeMessage(messageInfo,False,False) requestResponse = self.makeRequest(messageInfo, message) self.checkAuthorization(requestResponse,self._helpers.analyzeResponse(requestResponse.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected()) else: self.checkAuthorization(messageInfo,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected()) def makeRequest(self, messageInfo, message): requestURL = self._helpers.analyzeRequest(messageInfo).getUrl() return self._callbacks.makeHttpRequest(self._helpers.buildHttpService(str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https"), message) def makeMessage(self, messageInfo, removeOrNot, authorizeOrNot): requestInfo = self._helpers.analyzeRequest(messageInfo) headers = requestInfo.getHeaders() if removeOrNot: headers = list(headers) removeHeaders = ArrayList() removeHeaders.add(self.replaceString.getText()[0:self.replaceString.getText().index(":")]) for header in headers[:]: for removeHeader in removeHeaders: if removeHeader in header: headers.remove(header) if authorizeOrNot: headers.append(self.replaceString.getText()) msgBody = messageInfo.getRequest()[requestInfo.getBodyOffset():] return self._helpers.buildHttpMessage(headers, msgBody) def checkBypass(self,oldStatusCode,newStatusCode,oldContentLen,newContentLen,filters,requestResponse): analyzedResponse = self._helpers.analyzeResponse(requestResponse.getResponse()) impression = "" if oldStatusCode == newStatusCode: if oldContentLen == newContentLen: impression = self._enfocementStatuses[0] else: auth_enforced = 1 for filter in filters: if str(filter).startswith("Headers (simple string): "): if not(filter[25:] in self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])): auth_enforced = 0 if str(filter).startswith("Headers (regex): "): regex_string = filter[17:] p = re.compile(regex_string, re.IGNORECASE) if not p.search(self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])): auth_enforced = 0 if str(filter).startswith("Body (simple string): "): if not(filter[22:] in self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])): auth_enforced = 0 if str(filter).startswith("Body (regex): "): regex_string = filter[14:] p = re.compile(regex_string, re.IGNORECASE) if not p.search(self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])): auth_enforced = 0 if str(filter).startswith("Full request (simple string): "): if not(filter[30:] in self._helpers.bytesToString(requestResponse.getResponse())): auth_enforced = 0 if str(filter).startswith("Full request (regex): "): regex_string = filter[22:] p = re.compile(regex_string, re.IGNORECASE) if not p.search(self._helpers.bytesToString(requestResponse.getResponse())): auth_enforced = 0 if str(filter).startswith("Content-Length: "): if newContentLen != filter: auth_enforced = 0 if auth_enforced: impression = self._enfocementStatuses[2] else: impression = self._enfocementStatuses[1] else: impression = self._enfocementStatuses[2] return impression def checkAuthorization(self, messageInfo, originalHeaders, checkUnauthorized): message = self.makeMessage(messageInfo,True,True) requestResponse = self.makeRequest(messageInfo, message) analyzedResponse = self._helpers.analyzeResponse(requestResponse.getResponse()) oldStatusCode = originalHeaders[0] newStatusCode = analyzedResponse.getHeaders()[0] oldContentLen = self.getContentLength(originalHeaders) newContentLen = self.getContentLength(analyzedResponse.getHeaders()) # Check unauthorized request if checkUnauthorized: messageUnauthorized = self.makeMessage(messageInfo,True,False) requestResponseUnauthorized = self.makeRequest(messageInfo, messageUnauthorized) analyzedResponseUnauthorized = self._helpers.analyzeResponse(requestResponseUnauthorized.getResponse()) statusCodeUnauthorized = analyzedResponseUnauthorized.getHeaders()[0] contentLenUnauthorized = self.getContentLength(analyzedResponseUnauthorized.getHeaders()) EDFilters = self.EDModel.toArray() impression = self.checkBypass(oldStatusCode,newStatusCode,oldContentLen,newContentLen,EDFilters,requestResponse) if checkUnauthorized: EDFiltersUnauth = self.EDModelUnauth.toArray() impressionUnauthorized = self.checkBypass(oldStatusCode,statusCodeUnauthorized,oldContentLen,contentLenUnauthorized,EDFiltersUnauth,requestResponseUnauthorized) self._lock.acquire() row = self._log.size() if checkUnauthorized: self._log.add(LogEntry(self.currentRequestNumber,self._callbacks.saveBuffersToTempFiles(requestResponse), self._helpers.analyzeRequest(requestResponse).getUrl(),messageInfo,impression,self._callbacks.saveBuffersToTempFiles(requestResponseUnauthorized),impressionUnauthorized)) # same requests not include again. else: self._log.add(LogEntry(self.currentRequestNumber,self._callbacks.saveBuffersToTempFiles(requestResponse), self._helpers.analyzeRequest(requestResponse).getUrl(),messageInfo,impression,None,"Disabled")) # same requests not include again. self.fireTableRowsInserted(row, row) self.currentRequestNumber = self.currentRequestNumber + 1 self._lock.release() def getContentLength(self, analyzedResponseHeaders): for header in analyzedResponseHeaders: if "Content-Length:" in header: return header; return "null" def getCookieFromMessage(self, messageInfo): headers = list(self._helpers.analyzeRequest(messageInfo.getRequest()).getHeaders()) for header in headers: if "Cookie:" in header: return header return None
class BurpExtender(IBurpExtender, ITab, 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 JythonGui(ItemListener): def __init__(self, instructionsURI=''): self.instructionsURI = instructionsURI self.logger = logging.getLogger('sasi_runner_gui') self.logger.addHandler(logging.StreamHandler()) def log_fn(msg): self.log_msg(msg) self.logger.addHandler(FnLogHandler(log_fn)) self.logger.setLevel(logging.DEBUG) self.selected_input_file = None self.selected_output_file = None self.frame = JFrame( "SASI Runner", defaultCloseOperation = WindowConstants.EXIT_ON_CLOSE, ) self.frame.size = (650, 600,) self.main_panel = JPanel() self.main_panel.layout = BoxLayout(self.main_panel, BoxLayout.Y_AXIS) self.frame.add(self.main_panel) self.top_panel = JPanel(SpringLayout()) self.top_panel.alignmentX = Component.CENTER_ALIGNMENT self.main_panel.add(self.top_panel) self.stageCounter = 1 def getStageLabel(txt): label = JLabel("%s. %s" % (self.stageCounter, txt)) self.stageCounter += 1 return label # Instructions link. self.top_panel.add(getStageLabel("Read the instructions:")) instructionsButton = JButton( ('<HTML><FONT color="#000099">' '<U>open instructions</U></FONT><HTML>'), actionPerformed=self.browseInstructions) instructionsButton.setHorizontalAlignment(SwingConstants.LEFT); instructionsButton.setBorderPainted(False); instructionsButton.setOpaque(False); instructionsButton.setBackground(Color.WHITE); instructionsButton.setToolTipText(self.instructionsURI); self.top_panel.add(instructionsButton) # 'Select input' elements. self.top_panel.add(getStageLabel( "Select a SASI .zip file or data folder:")) self.top_panel.add( JButton("Select input...", actionPerformed=self.openInputChooser)) # 'Select output' elements. self.top_panel.add(getStageLabel("Specify an output file:")) self.top_panel.add( JButton("Specify output...", actionPerformed=self.openOutputChooser)) # 'Set result fields' elements. result_fields = [ {'id': 'gear_id', 'label': 'Gear', 'selected': True, 'enabled': False}, {'id': 'substrate_id', 'label': 'Substrate', 'selected': True}, {'id': 'energy_id', 'label': 'Energy', 'selected': False}, {'id': 'feature_id', 'label': 'Feature', 'selected': False}, {'id': 'feature_category_id', 'label': 'Feature Category', 'selected': False} ] self.selected_result_fields = {} resolutionLabelPanel = JPanel(GridLayout(0,1)) resolutionLabelPanel.add(getStageLabel("Set result resolution:")) resolutionLabelPanel.add( JLabel(("<html><i>This sets the specificity with which<br>" "results will be grouped. Note that enabling<br>" "more fields can *greatly* increase resulting<br>" "output sizes and run times.</i>"))) #self.top_panel.add(getStageLabel("Set result resolution:")) self.top_panel.add(resolutionLabelPanel) checkPanel = JPanel(GridLayout(0, 1)) self.top_panel.add(checkPanel) self.resultFieldCheckBoxes = {} for result_field in result_fields: self.selected_result_fields.setdefault( result_field['id'], result_field['selected']) checkBox = JCheckBox( result_field['label'], result_field['selected']) checkBox.setEnabled(result_field.get('enabled', True)) checkBox.addItemListener(self) checkPanel.add(checkBox) self.resultFieldCheckBoxes[checkBox] = result_field # 'Run' elements. self.top_panel.add(getStageLabel("Run SASI: (this might take a while)")) self.run_button = JButton("Run...", actionPerformed=self.runSASI) self.top_panel.add(self.run_button) SpringUtilities.makeCompactGrid( self.top_panel, self.stageCounter - 1, 2, 6, 6, 6, 6) # Progress bar. self.progressBar = JProgressBar(0, 100) self.main_panel.add(self.progressBar) # Log panel. self.log_panel = JPanel() self.log_panel.alignmentX = Component.CENTER_ALIGNMENT self.log_panel.setBorder(EmptyBorder(10,10,10,10)) self.main_panel.add(self.log_panel) self.log_panel.setLayout(BorderLayout()) self.log = JTextArea() self.log.editable = False self.logScrollPane = JScrollPane(self.log) self.logScrollPane.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS) self.logScrollBar = self.logScrollPane.getVerticalScrollBar() self.log_panel.add(self.logScrollPane, BorderLayout.CENTER) # File selectors self.inputChooser = JFileChooser() self.inputChooser.fileSelectionMode = JFileChooser.FILES_AND_DIRECTORIES self.outputChooser = JFileChooser() defaultOutputFile = os.path.join(System.getProperty("user.home"), "sasi_project.zip") self.outputChooser.setSelectedFile(File(defaultOutputFile)); self.outputChooser.fileSelectionMode = JFileChooser.FILES_ONLY self.frame.setLocationRelativeTo(None) self.frame.visible = True def browseInstructions(self, event): """ Open a browser to the instructions page. """ browseURI(self.instructionsURI) def itemStateChanged(self, event): """ Listen for checkbox changes. """ checkBox = event.getItemSelectable() is_selected = (event.getStateChange() == ItemEvent.SELECTED) result_field = self.resultFieldCheckBoxes[checkBox] self.selected_result_fields[result_field['id']] = is_selected def log_msg(self, msg): """ Print message to log and scroll to bottom. """ self.log.append(msg + "\n") self.log.setCaretPosition(self.log.getDocument().getLength()) def openInputChooser(self, event): ret = self.inputChooser.showOpenDialog(self.frame) if ret == JFileChooser.APPROVE_OPTION: self.selected_input_file = self.inputChooser.selectedFile self.log_msg("Selected '%s' as input." % self.selected_input_file.path) def openOutputChooser(self, event): ret = self.outputChooser.showSaveDialog(self.frame) if ret == JFileChooser.APPROVE_OPTION: selectedPath = self.outputChooser.selectedFile.path if not selectedPath.endswith('.zip'): zipPath = selectedPath + '.zip' self.outputChooser.setSelectedFile(File(zipPath)) self.selected_output_file = self.outputChooser.selectedFile self.log_msg( "Selected '%s' as output." % self.selected_output_file.path) def runSASI(self, event): try: self.validateParameters() except Exception as e: self.log_msg("ERROR: '%s'" % e) # Run task in a separate thread, so that log # messages will be shown as task progresses. def run_task(): self.tmp_dir = tempfile.mkdtemp(prefix="sasi_runner.") self.db_file = os.path.join(self.tmp_dir, "sasi_runner.db") self.progressBar.setValue(0) self.progressBar.setIndeterminate(True) def get_connection(): engine = create_engine('h2+zxjdbc:////%s' % self.db_file) con = engine.connect() return con try: # Set result fields. result_fields = [] for field_id, is_selected in self.selected_result_fields.items(): if is_selected: result_fields.append(field_id) task = RunSasiTask( input_path=self.selected_input_file.path, output_file=self.selected_output_file.path, logger=self.logger, get_connection=get_connection, config={ 'result_fields': result_fields, 'run_model': { 'run': { 'batch_size': 'auto', } }, 'output': { 'batch_size': 'auto', }, } ) task.call() except Exception as e: self.logger.exception("Could not complete task") self.progressBar.setIndeterminate(False) self.progressBar.setValue(100) try: shutil.rmtree(self.tmp_dir) except: pass Thread(target=run_task).start() def validateParameters(self): return True
class BurpExtender(IBurpExtender, IExtensionStateListener, IHttpListener, ITab, FocusListener, ActionListener, MouseAdapter): _version = "0.2" _name = "PyRules" _varsStorage = _name + "_vars" _scriptStorage = _name + "_script" _enabled = 0 _vars = {} def registerExtenderCallbacks(self, callbacks): print "Load:" + self._name + " " + self._version self.callbacks = callbacks self.helpers = callbacks.helpers #Create Tab layout self.jVarsPane = JTextPane() self.jVarsPane.setFont(Font('Monospaced', Font.PLAIN, 11)) self.jVarsPane.addFocusListener(self) self.jMenuPanel = JPanel() self.jLeftUpPanel = JPanel() self.jEnable = JCheckBox() self.jEnable.setFont(Font('Monospaced', Font.BOLD, 11)) self.jEnable.setForeground(Color(0, 0, 204)) self.jEnable.setText(self._name) self.jEnable.addActionListener(self) self.jDocs = JLabel() self.jDocs.setFont(Font('Monospaced', Font.PLAIN, 11)) self.jDocs.setForeground(Color(51, 102, 255)) self.jDocs.setText(Strings.docs_titel) self.jDocs.setToolTipText(Strings.docs_tooltip) self.jDocs.addMouseListener(self) self.jConsoleText = JTextArea() self.jConsoleText.setFont(Font('Monospaced', Font.PLAIN, 10)) self.jConsoleText.setBackground(Color(244, 246, 247)) self.jConsoleText.setEditable(0) self.jConsoleText.setWrapStyleWord(1) self.jConsoleText.setRows(10) self.jScrollConsolePane = JScrollPane() self.jScrollConsolePane.setViewportView(self.jConsoleText) #set initial text self.jConsoleText.setText(Strings.console_disable) self.jMenuPanelLayout = GroupLayout(self.jMenuPanel) self.jMenuPanel.setLayout(self.jMenuPanelLayout) self.jMenuPanelLayout.setHorizontalGroup( self.jMenuPanelLayout.createParallelGroup( GroupLayout.Alignment.LEADING).addGroup( self.jMenuPanelLayout.createSequentialGroup().addComponent( self.jEnable).addPreferredGap( LayoutStyle.ComponentPlacement.RELATED, 205, 32767).addComponent(self.jDocs))) self.jMenuPanelLayout.setVerticalGroup( self.jMenuPanelLayout.createParallelGroup( GroupLayout.Alignment.LEADING).addGroup( self.jMenuPanelLayout.createSequentialGroup().addGroup( self.jMenuPanelLayout.createParallelGroup( GroupLayout.Alignment.BASELINE).addComponent( self.jEnable).addComponent(self.jDocs)).addGap( 0, 7, 32767))) self.jConsolePane = JPanel() self.jConsoleLayout = GroupLayout(self.jConsolePane) self.jConsolePane.setLayout(self.jConsoleLayout) self.jConsoleLayout.setHorizontalGroup( self.jConsoleLayout.createParallelGroup( GroupLayout.Alignment.LEADING).addComponent( self.jScrollConsolePane)) self.jConsoleLayout.setVerticalGroup( self.jConsoleLayout.createParallelGroup( GroupLayout.Alignment.LEADING).addGroup( GroupLayout.Alignment.TRAILING, self.jConsoleLayout.createSequentialGroup().addComponent( self.jScrollConsolePane, GroupLayout.DEFAULT_SIZE, 154, 32767).addContainerGap())) self.jLeftUpPanelLayout = GroupLayout(self.jLeftUpPanel) self.jLeftUpPanel.setLayout(self.jLeftUpPanelLayout) self.jLeftUpPanelLayout.setHorizontalGroup( self.jLeftUpPanelLayout.createParallelGroup( GroupLayout.Alignment.LEADING).addComponent( self.jConsolePane, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, 32767).addComponent(self.jMenuPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) self.jLeftUpPanelLayout.setVerticalGroup( self.jLeftUpPanelLayout. createParallelGroup(GroupLayout.Alignment.LEADING).addGroup( GroupLayout.Alignment.TRAILING, self.jLeftUpPanelLayout.createSequentialGroup().addComponent( self.jMenuPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addPreferredGap( LayoutStyle.ComponentPlacement.RELATED).addComponent( self.jConsolePane, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, 32767))) self.jScrollpaneLeftDown = JScrollPane() self.jScrollpaneLeftDown.setViewportView(self.jVarsPane) self.jSplitPaneLeft = JSplitPane(JSplitPane.VERTICAL_SPLIT, self.jLeftUpPanel, self.jScrollpaneLeftDown) self.jSplitPaneLeft.setDividerLocation(300) self.jScriptPane = JTextPane() self.jScriptPane.setFont(Font('Monospaced', Font.PLAIN, 11)) self.jScriptPane.addMouseListener(self) self.JScrollPaneRight = JScrollPane() self.JScrollPaneRight.setViewportView(self.jScriptPane) self.jSplitPane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT, self.jSplitPaneLeft, self.JScrollPaneRight) self.jSplitPane.setDividerLocation(400) #Load saved saved settings ##Load vars vars = callbacks.loadExtensionSetting(self._varsStorage) if vars: vars = base64.b64decode(vars) else: # try to load the example try: with open("examples/Simple-CSRF-vars.py") as fvars: vars = fvars.read() # load the default text except: vars = Strings.vars ## initiate the persistant variables locals_ = {} try: exec(vars, {}, locals_) except Exception as e: print e self._vars = locals_ ## update the vars screen self.jVarsPane.document.insertString(self.jVarsPane.document.length, vars, SimpleAttributeSet()) ##Load script script = callbacks.loadExtensionSetting(self._scriptStorage) if script: script = base64.b64decode(script) else: # try to load the example try: with open("examples/Simple-CSRF-script.py") as fscript: script = fscript.read() # load the default text except: script = Strings.script ## compile the rules self._script = script self._code = '' try: self._code = compile(script, '<string>', 'exec') except Exception as e: print( '{}\nReload extension after you correct the error.'.format(e)) ## update the rules screen self.jScriptPane.document.insertString( self.jScriptPane.document.length, script, SimpleAttributeSet()) #Register Extension callbacks.customizeUiComponent(self.getUiComponent()) callbacks.addSuiteTab(self) callbacks.registerExtensionStateListener(self) callbacks.registerHttpListener(self) self.jScriptPane.requestFocus() def getUiComponent(self): return self.jSplitPane def getTabCaption(self): return self._name def actionPerformed(self, event): #Check box was clicked if self.jEnable == event.getSource(): if self._enabled == 1: self._enabled = 0 # console content shows help self.jConsoleText.setText(Strings.console_disable) else: self._enabled = 1 # console content displays the current persistent variable state self.jConsoleText.setText(Strings.console_state) self.jConsoleText.append(pformat(self._vars)) self.jConsoleText.append(Strings.extra_line) self.jConsoleText.append(Strings.console_log) return def mouseClicked(self, event): if event.source == self.jDocs: uri = URI.create("https://github.com/DanNegrea/PyRules") if uri and Desktop.isDesktopSupported() and Desktop.getDesktop( ).isSupported(Desktop.Action.BROWSE): Desktop.getDesktop().browse(uri) return def focusGained(self, event): if self.jConsolePane == event.getSource(): pass #print "Status pane gained focus" #debug return def focusLost(self, event): #Reinitialize the persistent values if self.jVarsPane == event.getSource(): # get the text from the pane end = self.jVarsPane.document.length vars = self.jVarsPane.document.getText(0, end) # compute the new values locals_ = {} exec(vars, {}, locals_) self._vars = locals_ # display the new result in console self.jConsoleText.append(Strings.console_state) self.jConsoleText.append(pformat(self._vars)) self.jConsoleText.append(Strings.extra_line) self.jConsoleText.append(Strings.console_log) # scroll to bottom verticalScrollBar = self.jScrollConsolePane.getVerticalScrollBar() verticalScrollBar.setValue(verticalScrollBar.getMaximum()) return def extensionUnloaded(self): try: #Save the latestest vars and script text ## save vars end = self.jVarsPane.document.length vars = self.jVarsPane.document.getText(0, end) vars = base64.b64encode(vars) self.callbacks.saveExtensionSetting(self._varsStorage, vars) ## save script/rules end = self.jScriptPane.document.length script = self.jScriptPane.document.getText(0, end) script = base64.b64encode(script) self.callbacks.saveExtensionSetting(self._scriptStorage, script) except Exception: traceback.print_exc(file=self.callbacks.getStderr()) print "Unloaded" #debug return def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): if self._enabled == 0: return try: locals_ = { 'extender': self, 'callbacks': self.callbacks, 'helpers': self.helpers, 'toolFlag': toolFlag, 'messageIsRequest': messageIsRequest, 'messageInfo': messageInfo, 'log': self.log } # add the _vars as gloval variables locals_ = dict(locals_, **self._vars) # execute the script/rules try: exec(self.getCode, {}, locals_) # catch exit() call inside the rule except SystemExit: pass # update the persistant variables by searching the local variables with the same name for key in self._vars: # assumption self._vars dictionary is smaller than locals_ if key in locals_: self._vars[key] = locals_[key] except Exception: traceback.print_exc(file=self.callbacks.getStderr()) return #Returns the compiled script @property def getCode(self): end = self.jScriptPane.document.length script = self.jScriptPane.document.getText(0, end) # if the script hasn't changed return the already compile text if script == self._script: return self._code self._script = script # compile, store and return the result self._code = compile(script, '<string>', 'exec') return self._code #Log the information into the console screen def log(self, obj): # if string just append. else use pformat from pprint if isinstance(obj, str): self.jConsoleText.append(obj + "\n") else: self.jConsoleText.append(pformat(obj) + "\n") # scroll to bottom verticalScrollBar = self.jScrollConsolePane.getVerticalScrollBar() verticalScrollBar.setValue(verticalScrollBar.getMaximum()) return
class ConsolePanel(Panel): def __init__(self): self.console = None self.outText = None self.inText = None self.outTextScroller = None self.nestedInputPanel = None self.directoryText = None Panel.__init__(self, "insets 0 0 0 0") def sendCommand(self, command): print str(self) oldText = self.inText.getText() self.inText.setText(command) self.inText.getActionListeners()[0].actionPerformed(None) self.inText.setText(oldText) def setDirectoryText(self, dirText): self.directoryText.setText(dirText) self.nestedInputPanel.revalidate() def write_out(self, text): if not self.outText: return self.outText.setText(self.outText.getText() + text) def initUI(self): font = Font("Courier New", Font.BOLD, 14) #create the output text panel self.outText = JTextArea() self.outText.setEditable(False) self.outText.setFont(font) self.outText.setWrapStyleWord(True) self.outText.setLineWrap(True) #self.outText.setLineWrap(True) #self.outText.setWrapStyleWord(True) class NoGhostScroller(JScrollPane): def paintComponent(self, g): g.setColor(self.getBackground()) g.fillRect(0, 0, self.getWidth(), self.getHeight()) #super(NoGhostScroller, self).paintComponent(g) self.outTextScroller = JScrollPane(self.outText) self.outTextScroller.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER) self.outTextScroller.getVerticalScrollBar().setForeground( Color(255, 0, 0)) #self.outText.setOpaque(False) self.outText.setBackground(Color(0, 20, 0)) self.outText.setForeground(Color.WHITE) #self.outTextScroller.setOpaque(False) self.outTextScroller.setBackground(Color(0, 20, 0)) #self.outText.repaint() #self.layered = JLayeredPane() #self.layered.setLayer(self.outTextScroller, 0) #create the input text box self.inText = JTextField() self.inText.setFocusTraversalKeysEnabled(False) self.inText.setFont(font) self.inText.setBackground(Color(0, 20, 0)) self.inText.setForeground(Color.WHITE) self.inText.getCaret().setVisible(True) self.inText.getCaret().setBlinkRate(500) self.inText.setCaretColor(Color(200, 255, 200)) class InFocusAdapter(FocusAdapter): def focusLost(adap, e): self.inText.setVisible(True) self.inText.addFocusListener(InFocusAdapter()) self.nestedInputPanel = Panel("Insets 0 0 0 0") #create the directory text box self.directoryText = JTextField() self.directoryText.setEditable(False) self.directoryText.setFont(font) self.directoryText.setBackground(Color(0, 20, 0)) self.directoryText.setForeground(Color.WHITE) #set up the console sys.stdout = FakeOut(self.outText) self.console = BashED_Console(stdout=sys.stdout) self.directoryText.setText(self.console.get_prompt()) self.revalidate() dirTex = self.directoryText #create the listener that fires when the 'return' key is pressed class InputTextActionListener(ActionListener): def __init__(self, parent, inp, out, console): self.parent = parent self.inp = inp self.out = out self.console = console def actionPerformed(self, e): #print self.getCommandText() # print(self.console.get_prompt()) # self.console.onecmd(self.inp.getText()) # self.parent.write_out("\n" + self.inp.getText()) # dirTex.setText(self.console.get_prompt()) # self.inp.setText("") self.parent.write_out(self.console.get_prompt() + self.inp.getText() + '\n') if 'clear' in self.inp.getText().split(' ')[0]: self.out.setText("") #clear the screen else: self.console.onecmd(self.inp.getText()) dirTex.setText(self.console.get_prompt()) self.inp.setText("") #create the listener that fires whenever a user hits a key class InputKeyActionListener(KeyAdapter): def __init__(self, parent, inp, out, console): self.parent = parent self.inp = inp self.out = out self.console = console def keyReleased(self, k): inp = self.inp.getText() if k.getKeyCode() == 9: #tab character autos = self.console.tabcomplete(self.inp.getText()) if len(autos) == 1: self.inp.setText(autos[0]) else: i = 0 for option in autos: self.parent.write_out(option) if i % 3 == 0: print('\n') else: print('\t') hist = None if k.getKeyCode() == 38: hist = self.console.next_hist() if k.getKeyCode() == 40: hist = self.console.last_hist() if hist: self.inp.setText(hist.rstrip('\n')) #prevent from firing self.inText.addActionListener( InputTextActionListener(self, self.inText, self.outText, self.console)) self.inText.addKeyListener( InputKeyActionListener(self, self.inText, self.outText, self.console)) def addUI(self): self.add(self.outTextScroller, "cell 0 0, push, grow") self.add(self.nestedInputPanel, "cell 0 1, pushx, growx") self.nestedInputPanel.add(self.directoryText, "cell 0 0") self.nestedInputPanel.add(self.inText, "cell 1 0, spanx, pushx, growx")
class ConsolePanel(Panel): def __init__(self): self.console = None self.outText = None self.inText = None self.outTextScroller = None self.nestedInputPanel = None self.directoryText = None Panel.__init__(self, "insets 0 0 0 0") def sendCommand(self, command): print str(self) oldText = self.inText.getText() self.inText.setText(command) self.inText.getActionListeners()[0].actionPerformed(None) self.inText.setText(oldText) def setDirectoryText(self, dirText): self.directoryText.setText(dirText) self.nestedInputPanel.revalidate() def write_out(self,text): if not self.outText: return self.outText.setText(self.outText.getText() + text) def initUI(self): font = Font("Courier New", Font.BOLD, 14) #create the output text panel self.outText = JTextArea() self.outText.setEditable(False) self.outText.setFont(font) self.outText.setWrapStyleWord(True) self.outText.setLineWrap(True) #self.outText.setLineWrap(True) #self.outText.setWrapStyleWord(True) class NoGhostScroller(JScrollPane): def paintComponent(self, g): g.setColor(self.getBackground()) g.fillRect(0, 0, self.getWidth(), self.getHeight()) #super(NoGhostScroller, self).paintComponent(g) self.outTextScroller = JScrollPane(self.outText) self.outTextScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER) self.outTextScroller.getVerticalScrollBar().setForeground(Color(255, 0, 0)) #self.outText.setOpaque(False) self.outText.setBackground(Color(0, 20, 0)) self.outText.setForeground(Color.WHITE) #self.outTextScroller.setOpaque(False) self.outTextScroller.setBackground(Color(0, 20, 0)) #self.outText.repaint() #self.layered = JLayeredPane() #self.layered.setLayer(self.outTextScroller, 0) #create the input text box self.inText = JTextField() self.inText.setFocusTraversalKeysEnabled(False) self.inText.setFont(font) self.inText.setBackground(Color(0, 20, 0)) self.inText.setForeground(Color.WHITE) self.inText.getCaret().setVisible(True) self.inText.getCaret().setBlinkRate(500) self.inText.setCaretColor(Color(200,255,200)) class InFocusAdapter(FocusAdapter): def focusLost(adap, e): self.inText.setVisible(True) self.inText.addFocusListener(InFocusAdapter()) self.nestedInputPanel = Panel("Insets 0 0 0 0") #create the directory text box self.directoryText = JTextField() self.directoryText.setEditable(False) self.directoryText.setFont(font) self.directoryText.setBackground(Color(0, 20, 0)) self.directoryText.setForeground(Color.WHITE) #set up the console sys.stdout = FakeOut(self.outText) self.console = BashED_Console(stdout=sys.stdout) self.directoryText.setText(self.console.get_prompt()) self.revalidate(); dirTex = self.directoryText; #create the listener that fires when the 'return' key is pressed class InputTextActionListener(ActionListener): def __init__(self,parent,inp,out,console): self.parent = parent self.inp = inp self.out = out self.console = console def actionPerformed(self, e): #print self.getCommandText() # print(self.console.get_prompt()) # self.console.onecmd(self.inp.getText()) # self.parent.write_out("\n" + self.inp.getText()) # dirTex.setText(self.console.get_prompt()) # self.inp.setText("") self.parent.write_out(self.console.get_prompt() + self.inp.getText() + '\n') if 'clear' in self.inp.getText().split(' ')[0]: self.out.setText("") #clear the screen else: self.console.onecmd(self.inp.getText()) dirTex.setText(self.console.get_prompt()) self.inp.setText("") #create the listener that fires whenever a user hits a key class InputKeyActionListener(KeyAdapter): def __init__(self,parent,inp,out,console): self.parent = parent self.inp = inp self.out = out self.console = console def keyReleased(self, k): inp = self.inp.getText() if k.getKeyCode() == 9: #tab character autos = self.console.tabcomplete(self.inp.getText()) if len(autos) == 1: self.inp.setText(autos[0]) else: i = 0 for option in autos: self.parent.write_out(option) if i % 3 == 0: print('\n') else: print('\t') hist = None if k.getKeyCode() == 38: hist = self.console.next_hist() if k.getKeyCode() == 40: hist = self.console.last_hist() if hist: self.inp.setText(hist.rstrip('\n'))#prevent from firing self.inText.addActionListener(InputTextActionListener(self,self.inText,self.outText,self.console)) self.inText.addKeyListener(InputKeyActionListener(self,self.inText,self.outText,self.console)) def addUI(self): self.add(self.outTextScroller, "cell 0 0, push, grow") self.add(self.nestedInputPanel, "cell 0 1, pushx, growx") self.nestedInputPanel.add(self.directoryText, "cell 0 0") self.nestedInputPanel.add(self.inText, "cell 1 0, spanx, pushx, growx")