コード例 #1
0
ファイル: ui.py プロジェクト: benteveo-kiwi/benteveo-toolbox
    def buildRequestTable(self, state, callbacks):
        """
        Builds the request list on the results page on the right.
        """
        splitpane = JSplitPane()
        splitpane.setDividerLocation(1000)

        endpointTable = Table(state.endpointTableModel)
        endpointTable.setDefaultRenderer(Class.forName('java.lang.Object'),
                                         CellHighlighterRenderer(state))

        endpointTable.getColumnModel().getColumn(0).setPreferredWidth(15)
        endpointTable.getColumnModel().getColumn(1).setPreferredWidth(500)
        endpointTable.setAutoCreateRowSorter(True)
        endpointTable.addMouseListener(TableMouseAdapter())

        endpointView = JScrollPane(endpointTable)
        callbacks.customizeUiComponent(endpointTable)
        callbacks.customizeUiComponent(endpointView)

        requestTable = Table(state.requestTableModel)
        requestTable.getColumnModel().getColumn(0).setPreferredWidth(500)

        requestView = JScrollPane(requestTable)
        callbacks.customizeUiComponent(requestTable)
        callbacks.customizeUiComponent(requestView)

        splitpane.setLeftComponent(endpointView)
        splitpane.setRightComponent(requestView)

        return splitpane
コード例 #2
0
ファイル: visualize.py プロジェクト: animanmaster/jyrimaa
    def initGui(self):
        def make_game_selector():
            self.gameChanger = False

            def dbChange(evt):
                if evt.source.text:
                    self.gamedb = GameDB(evt.source.text)
                    self.gameChanger = True

            def idChange(evt):
                if evt.source.text:
                    self.gameid = evt.source.text
                    self.gameChanger = True

            def turnChange(evt):
                if evt.source.text:
                    self.turnid = evt.source.text
                    self.gameChanger = True

            selector = JPanel()
            selector.add(JLabel("DB:"))
            selector.add(textfield(self.gamedb.dbfile, dbChange))
            selector.add(JLabel("Game ID:"))
            selector.add(textfield(self.gameid, idChange))
            selector.add(JLabel("Turn ID:"))
            selector.add(textfield(self.turnid, turnChange))
            return JScrollPane(selector)

        def make_content_panel():
            self.contentPanel = JPanel(GridLayout(1, 0, 5, 5))
            self.render()
            return JScrollPane(self.contentPanel)

        def save(self, txt, filename):
            pass

        def make_code_editor():
            import inspect
            panel = JPanel(BorderLayout(2, 2))
            self.codeArea = JTextArea()
            self.codeArea.text = self.scoringModule and inspect.getsource(
                self.scoringModule) or ""
            panel.add(JScrollPane(self.codeArea), BorderLayout.CENTER)
            return panel

        self.frame.contentPane.add(make_game_selector(), BorderLayout.NORTH)
        #        self.frame.contentPane.add(make_content_panel(), BorderLayout.WEST)
        #        self.frame.contentPane.add(make_code_editor(),   BorderLayout.CENTER)
        pane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT, make_content_panel(),
                          make_code_editor())
        pane.setDividerLocation(self.frame.width / 2)
        self.frame.contentPane.add(pane)
        reloadButton = JButton("Reload")

        def reload(evt):
            self.reload()

        reloadButton.addActionListener(reload)
        self.frame.contentPane.add(reloadButton, BorderLayout.SOUTH)
コード例 #3
0
ファイル: fileview.py プロジェクト: affilares/graph-ql
class FileView:
    """
    SplitPane containing an editoresque (Sublime-alike) filetree+editor widget
    """
    def __init__(self, dir=None, filetree_label=None, texteditor_factory=None):
        if not dir: dir = os.getcwd()
        self._filetree = FileTree(dir=dir, label=filetree_label)
        self._payloadview = PayloadView(texteditor_factory=texteditor_factory)
        self.this = JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                               self._filetree.this, self._payloadview.this)
        self.this.setOneTouchExpandable(True)
        self._filetree.add_tree_selection_listener(self._tree_listener)
        self.this.getRightComponent().setVisible(False)

    def _tree_listener(self, e):
        """
        Listen for tree selection and fill the payloadview

        :param e: unused
        :return: None
        """
        try:
            fpath = os.path.join(*[str(p) for p in e.getPath().getPath()][1:])

            if fpath.endswith('.html'):
                self.this.getRightComponent().setVisible(False)
                return

            with open(fpath, 'r') as f:
                payload = f.read()
                self._payloadview.set_editable(True)
                self._payloadview.refresh(payload)
                self.this.getRightComponent().setVisible(True)
                self.this.setDividerLocation(0.25)
        except IOError:
            pass

    def addTreeListener(self, action):
        """
        Add a new Tree ActionListener

        :param action: actionListener lambda
        :return:
        """
        self._filetree.add_tree_selection_listener(action)

    def addPayloadListener(self, action):
        """
        Add a new PayloadView Listener

        :param action: actionListener lambda
        :return:
        """
        self._payloadview.add_listener(action)

    def refresh(self):
        self._filetree.refresh()
コード例 #4
0
ファイル: visualize.py プロジェクト: animanmaster/jyrimaa
    def initGui(self):
        def make_game_selector():
            self.gameChanger = False
            def dbChange(evt):
                if evt.source.text: 
                    self.gamedb = GameDB(evt.source.text)
                    self.gameChanger = True
            def idChange(evt):
                if evt.source.text: 
                    self.gameid = evt.source.text
                    self.gameChanger = True
            def turnChange(evt):
                if evt.source.text: 
                    self.turnid = evt.source.text
                    self.gameChanger = True

            selector = JPanel()
            selector.add(JLabel("DB:"))
            selector.add(textfield(self.gamedb.dbfile, dbChange))
            selector.add(JLabel("Game ID:"))
            selector.add(textfield(self.gameid, idChange))
            selector.add(JLabel("Turn ID:"))
            selector.add(textfield(self.turnid, turnChange))
            return JScrollPane(selector)

        def make_content_panel():
            self.contentPanel = JPanel(GridLayout(1, 0, 5, 5))
            self.render()
            return JScrollPane(self.contentPanel)

        def save(self, txt, filename):
            pass
            
        def make_code_editor():
            import inspect
            panel = JPanel(BorderLayout(2,2))
            self.codeArea = JTextArea()
            self.codeArea.text = self.scoringModule and inspect.getsource(self.scoringModule) or ""
            panel.add(JScrollPane(self.codeArea), BorderLayout.CENTER)
            return panel

        self.frame.contentPane.add(make_game_selector(), BorderLayout.NORTH)
#        self.frame.contentPane.add(make_content_panel(), BorderLayout.WEST)
#        self.frame.contentPane.add(make_code_editor(),   BorderLayout.CENTER)
        pane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT, make_content_panel(), make_code_editor())
        pane.setDividerLocation(self.frame.width/2)
        self.frame.contentPane.add(pane)
        reloadButton = JButton("Reload")
        def reload(evt):
            self.reload()
        reloadButton.addActionListener(reload)
        self.frame.contentPane.add(reloadButton, BorderLayout.SOUTH)
コード例 #5
0
 def run(self):
     #-----------------------------------------------------------------------
     # Size the frame to use 1/2 of the screen
     #-----------------------------------------------------------------------
     screenSize = Toolkit.getDefaultToolkit().getScreenSize()
     frameSize = Dimension(screenSize.width >> 1, screenSize.height >> 1)
     frame = JFrame('javadocInfo',
                    size=frameSize,
                    defaultCloseOperation=JFrame.EXIT_ON_CLOSE)
     #-----------------------------------------------------------------------
     # Reposition the frame to be in the center of the screen
     #-----------------------------------------------------------------------
     frame.setLocation((screenSize.width - frameSize.width) >> 1,
                       (screenSize.height - frameSize.height) >> 1)
     #-----------------------------------------------------------------------
     # Initialize the list to have exactly 1 element
     #-----------------------------------------------------------------------
     self.List = JList(['One moment please...'],
                       valueChanged=self.pick,
                       selectionMode=ListSelectionModel.SINGLE_SELECTION)
     #-----------------------------------------------------------------------
     # Put the List in a ScrollPane and place it in the middle of a pane
     #-----------------------------------------------------------------------
     pane = JPanel(layout=BorderLayout())
     pane.add(JScrollPane(self.List), BorderLayout.CENTER)
     #-----------------------------------------------------------------------
     # Add a TextField [for the URL of the selected entry] at the bottom
     #-----------------------------------------------------------------------
     self.msg = JTextField()
     pane.add(self.msg, BorderLayout.SOUTH)
     #-----------------------------------------------------------------------
     # Add the pane and a scrollable TextArea to a SplitPane in the frame
     #-----------------------------------------------------------------------
     self.area = JTextArea()
     sPane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                        pane,
                        JScrollPane(self.area),
                        propertyChange=self.propChange)
     sPane.setDividerLocation(234)
     frame.add(sPane)
     #-----------------------------------------------------------------------
     # Create a separate thread to locate & proces the remote URL
     #-----------------------------------------------------------------------
     self.Links = {}  # Initialize the Links dictionary
     soupTask(
         self.List,  # The visible JList instance
         self.msg,  # The message area (JTextField)
         JAVADOC_URL,  # Remote web page URL to be processed
         self.Links  # Dictionary of links found
     ).execute()
     frame.setVisible(1)
コード例 #6
0
ファイル: ui.py プロジェクト: benteveo-kiwi/benteveo-toolbox
    def buildMessageViewer(self, state, callbacks):
        """
        Builds the panel that allows users to view requests on the results page.

        Args:
            state: the state object.
            callbacks: the burp callbacks object.
        """

        tabs = JTabbedPane()

        original = JSplitPane()
        original.setDividerLocation(1000)

        modified = JSplitPane()
        modified.setDividerLocation(1000)

        originalRequestEditor = MessageEditorController(state, "original")
        repeatedRequestEditor = MessageEditorController(state, "repeated")

        state.originalRequestViewer = callbacks.createMessageEditor(
            originalRequestEditor, False)
        state.originalResponseViewer = callbacks.createMessageEditor(
            originalRequestEditor, False)

        state.repeatedRequestViewer = callbacks.createMessageEditor(
            repeatedRequestEditor, False)
        state.repeatedResponseViewer = callbacks.createMessageEditor(
            repeatedRequestEditor, False)

        original.setLeftComponent(state.originalRequestViewer.getComponent())
        original.setRightComponent(state.originalResponseViewer.getComponent())

        modified.setLeftComponent(state.repeatedRequestViewer.getComponent())
        modified.setRightComponent(state.repeatedResponseViewer.getComponent())

        tabs.addTab("Original", original)
        tabs.addTab("Modified", modified)

        return tabs
コード例 #7
0
class MainPanel():
    """Represents the converted frame from NetBeans."""

    # default issue to populate the panel with
    defaultIssue = Issue(name="Name",
                         severity="Critical",
                         host="Host",
                         path="Path",
                         description="Description",
                         remediation="",
                         reqResp=RequestResponse(request="default request",
                                                 response="default response"))

    def loadPanel(self, issue):
        # type: (Issue) -> ()
        """Populates the panel with issue."""
        if issue is None:
            return

        # check if the input is the correct object
        assert isinstance(issue, Issue)

        # add selected issue to the panel to enable right-click stuff.
        self.selectedIssue = issue
        # set textfields and textareas
        self.textName.text = issue.name
        self.textHost.text = issue.host
        self.textPath.text = issue.path
        self.textAreaDescription.text = issue.description
        self.textAreaRemediation.text = issue.remediation
        self.textSeverity.text = issue.severity
        # request and response tabs
        self.panelRequest.setMessage(issue.getRequest(), True)
        self.panelResponse.setMessage(issue.getResponse(), False)

    # button actions
    def newIssueAction(self, event):
        """Pops up a frame to add a new issue."""
        frm = NewIssueDialog(callbacks=self.callbacks, title="New Issue")
        frm.display(self)

    def gotNewIssue(self, issue):
        """got a new issue."""
        self.tableIssue.addRow(issue)

    def editIssue(self, index, issue):
        """Issue has been edited."""
        self.tableIssue.editRow(index, issue)

    def deleteIssueAction(self, event):
        """Delete the currently selected issue."""
        # this is the button
        # btn = event.getSource()
        row = self.tableIssue.getTableSelectedRow()
        # YOLO
        self.tableIssue.deleteRow(row)
        # it works!

    def exportAction(self, event):
        """Export everything in the table to a file."""
        lastDir = ""
        try:
            # load the last used directory
            # this will probably change as we will use a base64 encoded json as the complete config?
            lastDir = self.callbacks.loadExtensionSetting("lastDir")
        except:
            # if there is not a last used directory in the settings, continue
            pass

        from Utils import saveFileDialog, writeFile
        selectedFile, usedDirectory = saveFileDialog(parent=self.panel,
                                                     startingDir=lastDir,
                                                     title="Export Issues",
                                                     extension="json")

        if selectedFile is not None:
            # write to the file
            writeFile(selectedFile.getAbsolutePath(),
                      self.tableIssue.exportIssues())

        if usedDirectory is not None:
            # overwrite the last used directory
            self.callbacks.saveExtensionSetting("lastDir", usedDirectory)

    def importAction(self, event):
        """Import a file to the table."""
        lastDir = ""
        try:
            # load the last used directory
            # this will probably change as we will use a base64 encoded json as the complete config?
            lastDir = self.callbacks.loadExtensionSetting("lastDir")
        except:
            # if there is not a last used directory in the settings, continue
            pass

        from Utils import openFileDialog
        selectedFile, usedDirectory = openFileDialog(parent=self.panel,
                                                     startingDir=lastDir,
                                                     title="Import Issues",
                                                     extension="json")

        # save the last directory
        self.callbacks.saveExtensionSetting("lastDir", usedDirectory)
        fi = open(selectedFile.getAbsolutePath(), "r")
        # read the file and create a list of Issues
        import json
        # newIssues = json.load(fi, object_hook=dictToIssue)
        # problem here is object_hook runs for every single object so newIssues
        # will have internal objects, even if we tag them

        from RequestResponse import RequestResponse, HttpService
        from base64 import b64decode
        issuesArray = json.load(fi)
        # now issuesArray is an array of dicts.
        # manual JSON deserialization - move this to a method/function?
        # also think about what happens if dictionaries are missing items
        newIssues = list()
        for eachissue in issuesArray:
            # now we have each issue
            # what if dictionaries are missing items?
            ht = HttpService(
                host=eachissue["reqResp"]["httpService"]["host"],
                port=eachissue["reqResp"]["httpService"]["port"],
                protocol=eachissue["reqResp"]["httpService"]["protocol"])
            rr = RequestResponse(
                request=b64decode(eachissue["reqResp"]["request"]),
                response=b64decode(eachissue["reqResp"]["response"]),
                comment=eachissue["reqResp"]["comment"],
                highlight=eachissue["reqResp"]["highlight"],
                httpService=ht)
            iss = Issue(name=eachissue["name"],
                        severity=eachissue["severity"],
                        host=eachissue["host"],
                        path=eachissue["path"],
                        description=eachissue["description"],
                        remediation=eachissue["remediation"],
                        reqResp=rr)

            # iss = Issue()
            # rr = RequestResponse()
            # ht = HttpService()
            newIssues.append(iss)

        # clear the table
        self.tableIssue.clear()
        # add the issues to the table
        # for iss in newIssues:
        #     self.tableIssue.addRow(iss)
        self.tableIssue.populate(newIssues)

    def newIssueFromBurp(self, invocation):
        """Create a New Issue from the context menu."""
        from Utils import getPath, bytesToString, burpToolName
        reqResp = invocation.getSelectedMessages()[0]
        host = str(reqResp.getHttpService())
        path = getPath(self.callbacks, reqResp)
        convertedReqResp = RequestResponse()
        convertedReqResp.fromIHttpRequestResponse(reqResp)
        tmpIssue = Issue(host=host, path=path, reqResp=convertedReqResp)
        # change the title to "New Issue from [TOOL]"?
        frameTitle = "New Issue from %s" % (burpToolName(
            invocation.getToolFlag()))
        frm = NewIssueDialog(callbacks=self.callbacks,
                             issue=tmpIssue,
                             title=frameTitle
                             #  , modality="application"
                             )
        frm.display(self)
        # FOCUS!
        frm.requestFocus()
        # print self.callbacks.getHelpers().bytesToString(reqResp[0].getRequest())

    # mostly converted generated code
    def __init__(self, callbacks, table=None):

        self.callbacks = callbacks
        self.jScrollPane1 = JScrollPane()
        self.jPanel1 = JPanel()
        self.labelName = JLabel("Name")
        self.textName = JTextField()
        self.labelSeverity = JLabel("Severity")
        self.textSeverity = JTextField()
        self.labelHost = JLabel("Host")
        self.labelPath = JLabel("Path")
        self.textHost = JTextField()
        self.textPath = JTextField()
        self.tabIssue = JTabbedPane()
        self.textAreaDescription = JTextArea()
        self.textAreaRemediation = JTextArea()
        # JScrollPanes to hold the two jTextAreas
        # put the textareas in JScrollPanes
        self.jsPaneDescription = JScrollPane(self.textAreaDescription)
        self.jsPaneRemediation = JScrollPane(self.textAreaRemediation)
        self.panelRequest = self.callbacks.createMessageEditor(None, False)
        self.panelResponse = self.callbacks.createMessageEditor(None, False)

        self.loadPanel(self.defaultIssue)

        # buttons
        self.buttonNewIssue = JButton("New Issue",
                                      actionPerformed=self.newIssueAction)
        self.buttonDeleteIssue = JButton(
            "Delete Issue", actionPerformed=self.deleteIssueAction)
        self.buttonImport = JButton("Import",
                                    actionPerformed=self.importAction)
        self.buttonExport = JButton("Export",
                                    actionPerformed=self.exportAction)

        if table is not None:
            self.tableIssue = table
        else:
            from IssueTable import IssueTable
            self.tableIssue = IssueTable()

        # wrap the table in a scrollpane
        self.jScrollPane1.setViewportView(self.tableIssue)

        # top panel containing the table
        from java.awt import Color
        self.jPanel1.setBorder(BorderFactory.createLineBorder(Color(0, 0, 0)))

        # create the labels and textfields
        self.textName.editable = False
        self.textName.setBackground(Color.LIGHT_GRAY)

        self.textSeverity.editable = False
        self.textSeverity.setBackground(Color.LIGHT_GRAY)

        self.textHost.editable = False
        self.textHost.setBackground(Color.LIGHT_GRAY)

        self.textPath.editable = False
        self.textPath.setBackground(Color.LIGHT_GRAY)

        # description textarea
        self.textAreaDescription.editable = False
        self.textAreaDescription.setLineWrap(True)
        self.textAreaDescription.setWrapStyleWord(True)
        self.tabIssue.addTab("Description", self.jsPaneDescription)

        # remediation textarea
        self.textAreaRemediation.editable = False
        self.textAreaRemediation.setLineWrap(True)
        self.textAreaRemediation.setWrapStyleWord(True)
        self.tabIssue.addTab("Remediation", self.jsPaneRemediation)

        # request tab
        self.panelRequest.setMessage("", True)
        self.tabIssue.addTab("Request", self.panelRequest.getComponent())

        # response tab
        self.panelResponse.setMessage("", False)
        self.tabIssue.addTab("Response", self.panelResponse.getComponent())

        # from java.lang import Short
        # jpanel1 is the bottom panel
        jPanel1Layout = GroupLayout(self.jPanel1)
        self.jPanel1.setLayout(jPanel1Layout)
        jPanel1Layout.setHorizontalGroup(
            # GroupLayout.Alignment.CENTER centers the group, in this case it
            # centers the buttons
            jPanel1Layout.createParallelGroup(
                GroupLayout.Alignment.CENTER
            ).addGroup(jPanel1Layout.createSequentialGroup().addContainerGap(
            ).addGroup(
                jPanel1Layout.createParallelGroup(
                    GroupLayout.Alignment.LEADING).
                addGroup(jPanel1Layout.createSequentialGroup().addGroup(
                    jPanel1Layout.createParallelGroup(
                        GroupLayout.Alignment.TRAILING).addComponent(
                            self.labelHost).addComponent(self.labelName)
                ).addPreferredGap(
                    LayoutStyle.ComponentPlacement.UNRELATED).addGroup(
                        jPanel1Layout.createParallelGroup(
                            GroupLayout.Alignment.LEADING).addGroup(
                                jPanel1Layout.createSequentialGroup(
                                ).addComponent(self.textName).addPreferredGap(
                                    LayoutStyle.ComponentPlacement.UNRELATED).
                                addComponent(
                                    self.labelSeverity).addPreferredGap(
                                        LayoutStyle.ComponentPlacement.
                                        RELATED).addComponent(
                                            self.textSeverity,
                                            GroupLayout.PREFERRED_SIZE, 186,
                                            GroupLayout.PREFERRED_SIZE)).
                        addGroup(
                            jPanel1Layout.createSequentialGroup().addComponent(
                                self.textHost, GroupLayout.PREFERRED_SIZE, 330,
                                GroupLayout.PREFERRED_SIZE).addPreferredGap(
                                    LayoutStyle.ComponentPlacement.RELATED
                                ).addComponent(self.labelPath).addPreferredGap(
                                    LayoutStyle.ComponentPlacement.RELATED).
                            addComponent(self.textPath)))).addComponent(
                                self.tabIssue)).addContainerGap()
                       ).addGroup(
                           jPanel1Layout.createSequentialGroup().addComponent(
                               self.buttonNewIssue).addComponent(
                                   self.buttonDeleteIssue).addComponent(
                                       self.buttonImport).addComponent(
                                           self.buttonExport)))

        # link size of buttons
        from javax.swing import SwingConstants
        jPanel1Layout.linkSize(SwingConstants.HORIZONTAL, [
            self.buttonDeleteIssue, self.buttonExport, self.buttonImport,
            self.buttonNewIssue
        ])

        jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(
        ).addGroup(
            jPanel1Layout.createSequentialGroup().addContainerGap().addGroup(
                jPanel1Layout.createParallelGroup(
                    GroupLayout.Alignment.BASELINE).addComponent(
                        self.labelName).addComponent(
                            self.textName, GroupLayout.PREFERRED_SIZE,
                            GroupLayout.DEFAULT_SIZE,
                            GroupLayout.PREFERRED_SIZE).addComponent(
                                self.labelSeverity).addComponent(
                                    self.textSeverity,
                                    GroupLayout.PREFERRED_SIZE,
                                    GroupLayout.DEFAULT_SIZE,
                                    GroupLayout.PREFERRED_SIZE)
            ).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(
                jPanel1Layout.createParallelGroup(
                    GroupLayout.Alignment.BASELINE).addComponent(
                        self.textHost, GroupLayout.PREFERRED_SIZE,
                        GroupLayout.DEFAULT_SIZE,
                        GroupLayout.PREFERRED_SIZE).addComponent(
                            self.labelPath).addComponent(
                                self.textPath, GroupLayout.PREFERRED_SIZE,
                                GroupLayout.DEFAULT_SIZE,
                                GroupLayout.PREFERRED_SIZE).addComponent(
                                    self.labelHost)).addPreferredGap(
                                        LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(self.tabIssue).addPreferredGap(
                LayoutStyle.ComponentPlacement.RELATED).addGroup(
                    jPanel1Layout.createParallelGroup().addComponent(
                        self.buttonNewIssue).addComponent(
                            self.buttonDeleteIssue).addComponent(
                                self.buttonImport).addComponent(
                                    self.buttonExport)).addContainerGap()))

        # create the main panel
        self.panel = JSplitPane(JSplitPane.VERTICAL_SPLIT)

        # set the top component
        self.panel.leftComponent = self.jScrollPane1
        self.panel.rightComponent = self.jPanel1
        self.panel.setDividerLocation(150)
コード例 #8
0
class BurpExtender(IBurpExtender, ISessionHandlingAction, ITab,
                   IContextMenuFactory, IContextMenuInvocation, ActionListener,
                   ITextEditor):

    #
    # implement IBurpExtender
    #

    def registerExtenderCallbacks(self, callbacks):
        # save the helpers for later
        self.helpers = callbacks.getHelpers()

        # set our extension name
        callbacks.setExtensionName("Custom Request Handler")
        callbacks.registerSessionHandlingAction(self)
        callbacks.registerContextMenuFactory(self)
        self._text_editor = callbacks.createTextEditor()
        self._text_editor.setEditable(False)

        #How much loaded the table row
        self.current_column_id = 0

        #GUI
        self._split_main = JSplitPane(JSplitPane.VERTICAL_SPLIT)
        self._split_top = JSplitPane(JSplitPane.HORIZONTAL_SPLIT)
        self._split_top.setPreferredSize(Dimension(100, 50))
        self._split_top.setDividerLocation(700)
        self._split_center = JSplitPane(JSplitPane.VERTICAL_SPLIT)

        boxVertical = swing.Box.createVerticalBox()
        box_top = swing.Box.createHorizontalBox()
        boxHorizontal = swing.Box.createHorizontalBox()
        buttonHorizontal = swing.Box.createHorizontalBox()
        boxVertical.add(boxHorizontal)

        box_regex = swing.Box.createVerticalBox()
        border = BorderFactory.createTitledBorder(LineBorder(Color.BLACK),
                                                  "Extract target strings",
                                                  TitledBorder.LEFT,
                                                  TitledBorder.TOP)
        box_regex.setBorder(border)

        self._add_btn = JButton("Add")
        self._add_btn.addActionListener(self)
        self._remove_btn = JButton("Remove")
        self._remove_btn.addActionListener(self)

        items = [
            'JSON',
            'Header',
        ]
        self._dropdown = JComboBox(items)
        type_panel = JPanel(FlowLayout(FlowLayout.LEADING))
        type_panel.add(JLabel('Type:'))
        type_panel.add(self._dropdown)

        self._jLabel_param = JLabel("Name:")
        self._param_error = JLabel("Name is required")

        self._param_error.setVisible(False)
        self._param_error.setFont(Font(Font.MONOSPACED, Font.ITALIC, 12))
        self._param_error.setForeground(Color.red)

        regex_checkbox = JPanel(FlowLayout(FlowLayout.LEADING))
        self._is_use_regex = JCheckBox("Extract from regex group")
        regex_checkbox.add(self._is_use_regex)
        self._jTextIn_param = JTextField(20)
        self._jLabel_regex = JLabel("Regex:")
        self._jTextIn_regex = JTextField(20)
        self._regex_error = JLabel("No group defined")
        self._regex_error.setVisible(False)
        self._regex_error.setFont(Font(Font.MONOSPACED, Font.ITALIC, 12))
        self._regex_error.setForeground(Color.red)

        self._param_panel = JPanel(FlowLayout(FlowLayout.LEADING))
        self._param_panel.add(self._jLabel_param)
        self._param_panel.add(self._jTextIn_param)
        self._param_panel.add(self._param_error)

        self._regex_panel = JPanel(FlowLayout(FlowLayout.LEADING))
        self._regex_panel.add(self._jLabel_regex)
        self._regex_panel.add(self._jTextIn_regex)
        self._regex_panel.add(self._regex_error)
        button_panel = JPanel(FlowLayout(FlowLayout.LEADING))
        #padding
        button_panel.add(JPanel())
        button_panel.add(JPanel())
        button_panel.add(JPanel())
        button_panel.add(self._add_btn)
        button_panel.add(self._remove_btn)
        box_regex.add(type_panel)
        box_regex.add(self._param_panel)
        box_regex.add(regex_checkbox)
        box_regex.add(self._regex_panel)
        buttonHorizontal.add(button_panel)
        box_regex.add(buttonHorizontal)
        boxVertical.add(box_regex)
        box_top.add(boxVertical)

        box_file = swing.Box.createHorizontalBox()
        checkbox_panel = JPanel(FlowLayout(FlowLayout.LEADING))
        border = BorderFactory.createTitledBorder(
            LineBorder(Color.BLACK), 'Payload Sets [Simple list]',
            TitledBorder.LEFT, TitledBorder.TOP)
        box_file.setBorder(border)

        box_param = swing.Box.createVerticalBox()
        box_param.add(checkbox_panel)

        file_column_names = [
            "Type",
            "Name",
            "Payload",
        ]
        data = []
        self.file_table_model = DefaultTableModel(data, file_column_names)
        self.file_table = JTable(self.file_table_model)
        self.file_table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF)

        column_model = self.file_table.getColumnModel()
        for count in xrange(column_model.getColumnCount()):
            column = column_model.getColumn(count)
            column.setPreferredWidth(160)

        self.file_table.preferredScrollableViewportSize = Dimension(500, 70)
        self.file_table.setFillsViewportHeight(True)

        panel_dropdown = JPanel(FlowLayout(FlowLayout.LEADING))
        self._file_dropdown = JComboBox(items)
        panel_dropdown.add(JLabel('Type:'))
        panel_dropdown.add(self._file_dropdown)
        box_param.add(panel_dropdown)
        box_param.add(JScrollPane(self.file_table))
        callbacks.customizeUiComponent(self.file_table)

        file_param_panel = JPanel(FlowLayout(FlowLayout.LEADING))

        self._file_param = JLabel("Name:")
        self._file_param_text = JTextField(20)

        file_param_panel.add(self._file_param)
        file_param_panel.add(self._file_param_text)
        self._error_message = JLabel("Name is required")
        self._error_message.setVisible(False)
        self._error_message.setFont(Font(Font.MONOSPACED, Font.ITALIC, 12))
        self._error_message.setForeground(Color.red)
        file_param_panel.add(self._error_message)
        box_param.add(file_param_panel)

        box_button_file = swing.Box.createVerticalBox()
        self._file_load_btn = JButton("Load")

        self._file_clear_btn = JButton("Clear")
        self._file_clear_btn.addActionListener(self)
        self._file_load_btn.addActionListener(self)
        box_button_file.add(self._file_load_btn)
        box_button_file.add(self._file_clear_btn)
        box_file.add(box_button_file)
        box_file.add(box_param)
        boxVertical.add(box_file)

        regex_column_names = [
            "Type",
            "Name",
            "Regex",
            "Start at offset",
            "End at offset",
        ]
        #clear target.json
        with open("target.json", "w") as f:
            pass
        data = []
        self.target_table_model = DefaultTableModel(data, regex_column_names)
        self.target_table = JTable(self.target_table_model)
        self.target_table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF)
        column_model = self.target_table.getColumnModel()
        for count in xrange(column_model.getColumnCount()):
            column = column_model.getColumn(count)
            column.setPreferredWidth(100)

        self.target_table.preferredScrollableViewportSize = Dimension(500, 70)
        self.target_table.setFillsViewportHeight(True)
        callbacks.customizeUiComponent(self.target_table)
        callbacks.customizeUiComponent(boxVertical)
        table_panel = swing.Box.createVerticalBox()
        table_panel.add(JScrollPane(self.target_table))
        box_top.add(table_panel)

        self._jScrollPaneOut = JScrollPane()
        #self._split_main.setBottomComponent(self._jScrollPaneOut)
        self._split_main.setBottomComponent(self._text_editor.getComponent())
        self._split_main.setTopComponent(box_top)
        self._split_main.setDividerLocation(450)
        callbacks.customizeUiComponent(self._split_main)
        callbacks.addSuiteTab(self)
        return

    def getTabCaption(self):
        return "CRH"

    def getUiComponent(self):
        return self._split_main

    def createMenuItems(self, invocation):
        menu = []
        ctx = invocation.getInvocationContext()
        menu.append(
            swing.JMenuItem("Send to CRH",
                            None,
                            actionPerformed=lambda x, inv=invocation: self.
                            menu_action(inv)))
        return menu if menu else None

    #
    # Implementation of Menu Action
    #
    def menu_action(self, invocation):
        try:
            invMessage = invocation.getSelectedMessages()
            message = invMessage[0].getResponse()
            res_info = self.helpers.analyzeResponse(message)
            send_res = message.tostring()
            self._text_editor.setText(send_res)
        except:
            print('Failed to add data to CRH tab.')

    #
    # Implementation of event action
    #
    def actionPerformed(self, actionEvent):

        # onclick add button of extract from regex group
        if actionEvent.getSource() is self._add_btn:
            start, end = self._text_editor.getSelectionBounds()
            value = None
            regex = None
            item = self._dropdown.getSelectedItem()
            param = self._jTextIn_param.getText()

            if len(param) is 0:
                self._param_error.setVisible(True)
                return
            self._param_error.setVisible(False)
            is_selected = self._is_use_regex.isSelected()
            if is_selected:
                start = None
                end = None
                regex = self._jTextIn_regex.getText()
                if len(regex) is 0:
                    self._regex_error.setVisible(True)
                    return

                req = self._text_editor.getText()
                try:
                    pattern = re.compile(regex)
                    match = pattern.search(req)
                    value = match.group(1) if match else None
                    if value is None:
                        raise IndexError
                except IndexError:
                    self._regex_error.setVisible(True)
                    return
                self._regex_error.setVisible(False)

            data = [
                item,
                param,
                regex,
                start,
                end,
            ]
            self.target_table_model.addRow(data)

            with open("target.json", "r+") as f:
                try:
                    json_data = json.load(f)
                except ValueError:
                    json_data = dict()
                if is_selected:
                    data = {
                        param: [
                            item,
                            regex,
                        ]
                    }
                else:
                    data = {
                        param: [
                            item,
                            start,
                            end,
                        ]
                    }
                json_data.update(data)
                self.write_file(f, json.dumps(json_data))

        # onclick remove button of extract from regex group
        if actionEvent.getSource() is self._remove_btn:
            rowno = self.target_table.getSelectedRow()
            if rowno != -1:
                column_model = self.target_table.getColumnModel()
                param_name = self.target_table_model.getValueAt(rowno, 1)
                start = self.target_table_model.getValueAt(rowno, 3)

                self.target_table_model.removeRow(rowno)
                with open("target.json", 'r+') as f:
                    try:
                        json_data = json.load(f)
                    except ValueError:
                        json_data = dict()

                    for key, value in json_data.items():
                        if value[1] == start and key == param_name:
                            try:
                                del json_data[key]
                            except IndexError:
                                print('Error: {0}: No such json key.'.format(
                                    key))
                    self.write_file(f, json.dumps(json_data))

        # onclick load button of payload sets
        if actionEvent.getSource() is self._file_load_btn:
            #clear table
            self.remove_all(self.file_table_model)
            self.current_column_id = 0

            target_param = self._file_param_text.getText()
            item = self._file_dropdown.getSelectedItem()

            if len(target_param) == 0:
                self._error_message.setVisible(True)
                return
            self._error_message.setVisible(False)

            chooser = JFileChooser()
            chooser.showOpenDialog(actionEvent.getSource())
            file_path = chooser.getSelectedFile().getAbsolutePath()
            with open(file_path, 'r') as f:
                while True:
                    line = f.readline().strip()
                    if not line:
                        break
                    data = [
                        item,
                        target_param,
                        line,
                    ]
                    self.file_table_model.addRow(data)

            with open('target.json', 'r+') as f:
                try:
                    json_data = json.load(f)
                except ValueError:
                    json_data = dict()

                json_data.update({target_param: [
                    item,
                    'Set payload',
                ]})
                self.write_file(f, json.dumps(json_data))

        # onclick clear button of payload sets
        if actionEvent.getSource() is self._file_clear_btn:
            self.remove_all(self.file_table_model)

            self.current_column_id = 0

            with open("target.json", 'r+') as f:
                try:
                    json_data = json.load(f)
                except:
                    json_data = dict()

                for key, value in json_data.items():
                    if isinstance(value[1], unicode):
                        if value[1].encode('utf-8') == 'Set payload':
                            try:
                                del json_data[key]
                            except IndexError:
                                print('Error: {0}: No such json key.'.format(
                                    key))
                self.write_file(f, json.dumps(json_data))

    #
    # Implementaion of ISessionHandlingAction
    #
    def getActionName(self):
        return "custom request handler"

    def performAction(self, current_request, macro_items):

        if len(macro_items) == 0:
            return

        # extract the response headers
        final_response = macro_items[len(macro_items) - 1].getResponse()
        if final_response is None:
            return

        req = self.helpers.analyzeRequest(current_request)

        try:
            with open('target.json', 'r') as f:
                read_data = f.read()
                self.read_data = json.loads(read_data)
        except ValueError:
            sys.stderr.write('Error: json.loads()')
            return

        for key, value in self.read_data.items():
            if value[0] == 'JSON':
                self.set_json_parameter(current_request, final_response, key,
                                        value)
            elif value[0] == 'Header':
                self.set_header(current_request, final_response, key, value)

    def set_json_parameter(self, current_request, final_response, key, value):
        req = self.helpers.analyzeRequest(current_request)

        if IRequestInfo.CONTENT_TYPE_JSON != req.getContentType():
            return False

        body = current_request.getRequest()[req.getBodyOffset():].tostring()
        json_data = json.loads(body, object_pairs_hook=collections.OrderedDict)

        target_keys = filter(lambda x: x == key, json_data.keys())
        if not target_keys:
            return

        req_data = json_data
        column_model = self.file_table.getColumnModel()
        row_count = self.file_table_model.getRowCount()
        for key in target_keys:
            if value[-1] == 'Set payload':
                if row_count > self.current_column_id:
                    req_value = self.file_table_model.getValueAt(
                        self.current_column_id, 2)
                    self.current_column_id += 1
            else:
                # No selected regex
                if len(value) > 2:
                    start, end = value[1:]
                    req_value = final_response[start:end].tostring()
                else:
                    regex = value[1]
                    match = re.search(regex, final_response.tostring())
                    req_value = match.group(1) if match else None

            req_data[key] = req_value

        req = current_request.getRequest()
        json_data_start = self.helpers.indexOf(req, bytearray(body), False, 0,
                                               len(req))

        # glue together header + customized json of request
        current_request.setRequest(
            req[0:json_data_start] +
            self.helpers.stringToBytes(json.dumps(req_data)))

    def set_header(self, current_request, final_response, key, value):
        req = self.helpers.analyzeRequest(current_request)
        headers = req.getHeaders()
        target_keys = []
        for header in headers:
            if header.startswith(key):
                target_keys += [key]

        if not target_keys:
            return

        column_model = self.file_table.getColumnModel()
        row_count = self.file_table_model.getRowCount()
        req = current_request.getRequest()

        for key in target_keys:
            if value[-1] == 'Set payload':
                if row_count > self.current_column_id:
                    req_value = self.file_table_model.getValueAt(
                        self.current_column_id, 2)
                    self.current_column_id += 1
            else:
                # No selected regex
                if len(value) > 2:
                    start, end = value[1:]
                    req_value = final_response[start:end].tostring()
                else:
                    regex = value[1]
                    match = re.search(regex, final_response.string())
                    req_value = match.group(1) if match else None

            key_start = self.helpers.indexOf(req,
                                             bytearray(key.encode('utf-8')),
                                             False, 0, len(req))
            key_end = self.helpers.indexOf(req, bytearray('\r\n'), False,
                                           key_start, len(req))

            keylen = len(key)

        # glue together first line + customized hedaer + rest of request
        current_request.setRequest(
            req[0:key_start] +
            self.helpers.stringToBytes("%s: %s" %
                                       (key.encode('utf-8'), req_value)) +
            req[key_end:])

    #
    # Implementation of function for Remove all for specific table data
    #
    def remove_all(self, model):
        count = model.getRowCount()
        for i in xrange(count):
            model.removeRow(0)

    #
    # Implementaion of function for write data for specific file
    #
    def write_file(self, f, data):
        f.seek(0)
        f.write(data)
        f.truncate()
        return
コード例 #9
0
class BurpExtender(IBurpExtender, ITab):
    def registerExtenderCallbacks(self, callbacks):
        print "Loading..."

        self._callbacks = callbacks
        self._callbacks.setExtensionName('Burp SPA Explorer')
        # self._callbacks.registerScannerCheck(self)
        # self._callbacks.registerExtensionStateListener(self)
        self._helpers = callbacks.getHelpers()

        self.crawlingEvent = Event()
        self.crawlerThread = None

        # main split pane
        self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT)
        self._splitpane.setBorder(EmptyBorder(20, 20, 20, 20))

        # sub split pane (top)
        self._topPanel = JPanel(BorderLayout(10, 10))
        self._topPanel.setBorder(EmptyBorder(0, 0, 10, 0))

        # Setup Panel :    [Target: ] [______________________] [START BUTTON]
        self.setupPanel = JPanel(FlowLayout(FlowLayout.LEADING, 10, 10))

        self.setupPanel.add(JLabel("Target:", SwingConstants.LEFT),
                            BorderLayout.LINE_START)

        self.hostField = JTextField('', 50)
        self.setupPanel.add(self.hostField)

        self.toggleButton = JButton('Start crawling',
                                    actionPerformed=self.toggleCrawl)
        self.setupPanel.add(self.toggleButton)

        self._topPanel.add(self.setupPanel, BorderLayout.PAGE_START)

        # Options Panel :    [Buttons]  [          RegEx           ]
        self.optionsPanel = JPanel()
        self.optionsPanel.setLayout(
            BoxLayout(self.optionsPanel, BoxLayout.LINE_AXIS))

        # Button options panel :    [Add][Edit][Up][Down][Remove]

        self.buttonOptionsPanel = JPanel()
        self.buttonOptionsPanel.setLayout(
            BoxLayout(self.buttonOptionsPanel, BoxLayout.PAGE_AXIS))

        self.addRegexButton = JButton('Add', actionPerformed=self.addRegex)
        self.buttonOptionsPanel.add(self.addRegexButton)

        self.editRegexButton = JButton('Edit', actionPerformed=self.editRegex)
        self.buttonOptionsPanel.add(self.editRegexButton)

        self.moveRegexUpButton = JButton('Move up',
                                         actionPerformed=self.moveRegexUp)
        self.buttonOptionsPanel.add(self.moveRegexUpButton)

        self.moveRegexDownButton = JButton('Move down',
                                           actionPerformed=self.moveRegexDown)
        self.buttonOptionsPanel.add(self.moveRegexDownButton)

        self.removeRegexButton = JButton('Remove',
                                         actionPerformed=self.removeRegex)
        self.buttonOptionsPanel.add(self.removeRegexButton)

        self.buttonOptionsPanel.add(Box.createVerticalGlue())

        self.optionsPanel.add(self.buttonOptionsPanel)

        self.optionsPanel.add(Box.createHorizontalStrut(20))

        self.regexTableModel = RegexTableModel([x for x in regex])
        self.regexTable = Table(self.regexTableModel)
        self.regexScrollPane = JScrollPane(self.regexTable)

        self.optionsPanel.add(self.regexScrollPane)

        self._topPanel.add(self.optionsPanel, BorderLayout.CENTER)
        self._splitpane.setTopComponent(self._topPanel)

        # Bottom Panel
        self._bottomPanel = JPanel(BorderLayout(10, 10))
        #self._bottomPanel.setLayout(BoxLayout(self._bottomPanel,BoxLayout.PAGE_AXIS))

        # Status bar
        self.crawlStatusPanel = JPanel(FlowLayout(FlowLayout.LEADING, 10, 10))

        self.crawlStatusPanel.add(JLabel("Status: ", SwingConstants.LEFT))

        self.crawlStatusLabel = JLabel("Ready to crawl", SwingConstants.LEFT)
        self.crawlStatusPanel.add(self.crawlStatusLabel)

        # Result Table
        self.resultTableModel = Result([])
        self.resultTable = Table(self.resultTableModel)
        self.resultTable.setAutoCreateRowSorter(True)
        self.resultScrollPane = JScrollPane(self.resultTable)

        # Result Table popup menu
        def selectWhenRightClickEvent(event):
            def select(e):
                rowAtPoint = self.resultTable.rowAtPoint(
                    SwingUtilities.convertPoint(self.resultTablePopupMenu,
                                                Point(0, 0), self.resultTable))
                if rowAtPoint > -1:
                    self.resultTable.setRowSelectionInterval(
                        rowAtPoint, rowAtPoint)

            SwingUtilities.invokeLater(CrawlerRunnable(select, (event, )))

        self.resultTablePopupMenu = JPopupMenu(
            popupMenuWillBecomeVisible=selectWhenRightClickEvent)
        self.resultTablePopupMenu.add(
            JMenuItem("Send to scanner", actionPerformed=self.sendToScanner))
        self.resultTablePopupMenu.add(
            JMenuItem("Send to repeater", actionPerformed=self.sendToRepeater))
        self.resultTablePopupMenu.add(
            JMenuItem("Send to intruder", actionPerformed=self.sendToIntruder))
        self.resultTablePopupMenu.add(
            JMenuItem("Send to spider", actionPerformed=self.sendToSpider))

        self.resultTable.setComponentPopupMenu(self.resultTablePopupMenu)

        self._bottomPanel.add(self.resultScrollPane, BorderLayout.CENTER)
        self._bottomPanel.add(self.crawlStatusPanel, BorderLayout.SOUTH)

        self._splitpane.setBottomComponent(self._bottomPanel)
        self._splitpane.setDividerLocation(300 +
                                           self._splitpane.getInsets().left)

        callbacks.customizeUiComponent(self._splitpane)

        callbacks.addSuiteTab(self)

        explorerMenu = ExplorerMenu(self)
        callbacks.registerContextMenuFactory(explorerMenu)
        print "SPA Explorer custom menu loaded"

        #print "Loading chrome driver"
        #a = Test(os.path.dirname(os.path.realpath('selenium-client.jar')) + '/chromedriver.exe')
        #print "Chrome driver started"

        print "Burp SPA Explorer loaded"

    # Button Actions

    def getURLComponents(self, url):
        return (url.getHost(), (443 if url.getProtocol() == 'https' else 80)
                if url.getPort() == -1 else url.getPort(),
                url.getProtocol() == 'https')

    def sendToScanner(self, event):
        url = URL(
            self.resultTable.getValueAt(self.resultTable.getSelectedRow(), 1))
        urlComp = self.getURLComponents(url)
        self._callbacks.doActiveScan(urlComp[0], urlComp[1], urlComp[2],
                                     self._helpers.buildHttpRequest(url))

    def sendToRepeater(self, event):
        url = URL(
            self.resultTable.getValueAt(self.resultTable.getSelectedRow(), 1))
        urlComp = self.getURLComponents(url)
        self._callbacks.sendToRepeater(urlComp[0], urlComp[1], urlComp[2],
                                       self._helpers.buildHttpRequest(url),
                                       None)

    def sendToIntruder(self, event):
        url = URL(
            self.resultTable.getValueAt(self.resultTable.getSelectedRow(), 1))
        urlComp = self.getURLComponents(url)
        self._callbacks.sendToIntruder(urlComp[0], urlComp[1], urlComp[2],
                                       self._helpers.buildHttpRequest(url))

    def sendToSpider(self, event):
        url = URL(
            self.resultTable.getValueAt(self.resultTable.getSelectedRow(), 1))
        self._callbacks.sendToSpider(url)

    def addRegex(self, event):
        optionPane = JOptionPane()
        dialog = optionPane.createDialog(self._splitpane, "Add RegEx")

        panel = JPanel(GridLayout(0, 2))
        panel.setBorder(EmptyBorder(10, 10, 10, 10))

        nameField = JTextField('', 15)
        panel.add(JLabel("Name:", SwingConstants.LEFT))
        panel.add(nameField)

        regexField = JTextField('', 15)
        panel.add(JLabel("RegEx:", SwingConstants.LEFT))
        panel.add(regexField)

        crawlField = JCheckBox()
        panel.add(JLabel("Crawl:", SwingConstants.LEFT))
        panel.add(crawlField)

        def closeDialog(event):
            if len(nameField.text) == 0 or len(regexField.text) == 0:
                JOptionPane.showMessageDialog(self._splitpane,
                                              "Name or RegEx can't be empty",
                                              "Error",
                                              JOptionPane.ERROR_MESSAGE)
                return
            self.regexTableModel.addRow(
                [nameField.text, regexField.text,
                 crawlField.isSelected()])
            dialog.hide()

        addButton = JButton('OK', actionPerformed=closeDialog)
        panel.add(addButton)

        dialog.setSize(600, 200)
        dialog.setContentPane(panel)
        self._callbacks.customizeUiComponent(dialog)
        dialog.show()

        return True

    def editRegex(self, event):
        selectedRowIdx = self.regexTable.getSelectedRow()
        if selectedRowIdx == -1: return False
        selectedRow = self.regexTableModel.data[selectedRowIdx]

        optionPane = JOptionPane()
        dialog = optionPane.createDialog(self._splitpane, "Edit RegEx")

        panel = JPanel(GridLayout(0, 2))
        panel.setBorder(EmptyBorder(10, 10, 10, 10))

        nameField = JTextField('', 15)
        nameField.text = selectedRow[0]
        panel.add(JLabel("Name:", SwingConstants.LEFT))
        panel.add(nameField)

        regexField = JTextField('', 15)
        regexField.text = selectedRow[1]
        panel.add(JLabel("RegEx:", SwingConstants.LEFT))
        panel.add(regexField)

        crawlField = JCheckBox()
        crawlField.setSelected(selectedRow[2])
        panel.add(JLabel("Crawl:", SwingConstants.LEFT))
        panel.add(crawlField)

        def closeDialog(event):
            if len(nameField.text) == 0 or len(regexField.text) == 0:
                JOptionPane.showMessageDialog(self._splitpane,
                                              "Name or RegEx can't be empty",
                                              "Error",
                                              JOptionPane.ERROR_MESSAGE)
                return
            self.regexTableModel.editRow(
                selectedRowIdx,
                [nameField.text, regexField.text,
                 crawlField.isSelected()])
            dialog.hide()

        editButton = JButton('OK', actionPerformed=closeDialog)
        panel.add(editButton)

        dialog.setSize(600, 200)
        dialog.setContentPane(panel)
        self._callbacks.customizeUiComponent(dialog)
        dialog.show()
        return True

    def moveRegexDown(self, event):
        idxs = self.regexTable.getSelectedRows()
        if self.regexTableModel.getRowCount() - 1 in idxs: return False

        self.regexTable.clearSelection()
        for i in sorted(idxs)[::-1]:
            self.regexTableModel.moveDown(i)
            self.regexTable.addRowSelectionInterval(i + 1, i + 1)
        return True

    def moveRegexUp(self, event):
        idxs = self.regexTable.getSelectedRows()
        if 0 in idxs: return False

        self.regexTable.clearSelection()
        for i in sorted(idxs):
            self.regexTableModel.moveUp(i)
            self.regexTable.addRowSelectionInterval(i - 1, i - 1)
        return True

    def removeRegex(self, event):
        idx = self.regexTable.getSelectedRows()
        for i in sorted(idx)[::-1]:
            self.regexTableModel.removeRow(i)
        return True

    # Implement ITab

    def getTabCaption(self):
        return "SPA Explorer"

    def getUiComponent(self):
        return self._splitpane

    def crawl(self, event):
        print("Starting")

        host = self.hostField.text

        if host.find("://") == -1:
            host = "http://" + host

        try:
            self._callbacks.includeInScope(URL(host))
        except:
            JOptionPane.showMessageDialog(self._splitpane,
                                          "Can't add host to scope", "Error",
                                          JOptionPane.ERROR_MESSAGE)
            return

        self.resultTableModel.clearAllRow()

        self.crawlingEvent.set()
        self.crawlerThread = Thread(target=self.crawl_thread, args=(host, ))
        self.crawlerThread.start()
        print("Started")

    def stopCrawling(self, event):
        print("Clear event")
        self.crawlingEvent.clear()

        # Disable button
        if self.toggleButton.text == "Stop crawling":  # If button is still "Stop crawling" (Thread still running), disable button
            self.toggleButton.setEnabled(False)

    def toggleCrawl(self, event):
        if (self.crawlerThread == None or not self.crawlerThread.is_alive()):
            self.crawl(event)
            #self.toggleButton.setText("Start crawling")
        else:
            self.stopCrawling(event)
            #self.toggleButton.setText("Stop crawling")

    def crawl_thread(self, host):
        # print(self, host)
        print("Crawl thread started")

        SwingUtilities.invokeLater(
            CrawlerRunnable(self.toggleButton.setText, ("Stop crawling", )))
        SwingUtilities.invokeLater(
            CrawlerRunnable(self.addRegexButton.setEnabled, (False, )))
        SwingUtilities.invokeLater(
            CrawlerRunnable(self.editRegexButton.setEnabled, (False, )))
        SwingUtilities.invokeLater(
            CrawlerRunnable(self.moveRegexUpButton.setEnabled, (False, )))
        SwingUtilities.invokeLater(
            CrawlerRunnable(self.moveRegexDownButton.setEnabled, (False, )))
        SwingUtilities.invokeLater(
            CrawlerRunnable(self.removeRegexButton.setEnabled, (False, )))

        pageType = {}  # url -> type
        pageContentHash = {}  # hash -> url list

        def concatURL(baseURL, link):
            return URL(URL(baseURL), link).toString()

        def makeRequest(url):
            url = URL(url)

            if not self._callbacks.isInScope(url):
                #self.logger.addRow(url.toString()+" is out of scope")
                raise ValueError("URL is out of scope")

            prot = url.getProtocol()
            host = url.getHost()
            port = url.getPort()
            if port == -1:
                port = 80 if prot == "http" else 443

            httpService = self._helpers.buildHttpService(host, port, prot)

            reqRes = self._callbacks.makeHttpRequest(
                httpService, self._helpers.buildHttpRequest(url))
            self._callbacks.addToSiteMap(reqRes)
            resp = reqRes.getResponse()
            respInfo = self._helpers.analyzeResponse(resp)

            respBody = self._helpers.bytesToString(
                resp[respInfo.getBodyOffset():])
            return respBody

        def matchRegex(baseURL, res):
            toRet = []
            for (name, regStr, ret) in self.regexTableModel.data:
                matchObj = re.findall(regStr, res, re.M | re.I)
                for i in matchObj:
                    try:
                        if i.find('http://') == 0 or i.find('https://') == 0:
                            url = i
                        elif i[0] == '/':
                            url = host + i
                        else:
                            url = host + '/' + i

                        if url not in pageType:
                            pageType[url] = name
                            SwingUtilities.invokeLater(
                                CrawlerRunnable(self.resultTableModel.addRow,
                                                ([name, url], )))

                            if ret:
                                toRet.append(url)
                    except:
                        print("Error when trying to save result ", i,
                              sys.exc_info()[0],
                              sys.exc_info()[1])
            return toRet

        def getAllLink(url):
            toRet = []
            try:
                print("Making request", url)
                r = makeRequest(url)
                print("Done request", len(r))
                hash = hashlib.sha256(r.encode('utf-8')).hexdigest()
                #print(r.text)
                if hash in pageContentHash:
                    print("Content hash is the same as ",
                          pageContentHash[hash][0])
                    pageContentHash[hash].append(url)
                    return toRet
                else:
                    pageContentHash[hash] = [url]

                toRet += matchRegex(url, r)
            except BaseException as e:
                print("Error while making request to ", url, e)
            except:
                print("Error while making request to ", url,
                      sys.exc_info()[0],
                      sys.exc_info()[1])
            return toRet

        crawledPage = [host]
        crawledNow = 0

        SwingUtilities.invokeLater(
            CrawlerRunnable(self.resultTableModel.addRow,
                            (["TARGET", host], )))

        while crawledNow < len(crawledPage):
            if self.crawlingEvent.is_set():
                print("Crawling", crawledPage[crawledNow])
                SwingUtilities.invokeLater(
                    CrawlerRunnable(self.crawlStatusLabel.setText,
                                    ("Crawling " + crawledPage[crawledNow], )))
                for i in getAllLink(crawledPage[crawledNow]):
                    if i not in crawledPage:
                        print("ADD:", i)
                        crawledPage.append(i)
                crawledNow += 1
            else:
                print("Stop Requested")
                break

        print(crawledNow, crawledPage)
        output = []

        SwingUtilities.invokeLater(
            CrawlerRunnable(self.toggleButton.setText, ("Start crawling", )))
        SwingUtilities.invokeLater(
            CrawlerRunnable(self.toggleButton.setEnabled, (True, )))
        SwingUtilities.invokeLater(
            CrawlerRunnable(self.addRegexButton.setEnabled, (True, )))
        SwingUtilities.invokeLater(
            CrawlerRunnable(self.editRegexButton.setEnabled, (True, )))
        SwingUtilities.invokeLater(
            CrawlerRunnable(self.moveRegexUpButton.setEnabled, (True, )))
        SwingUtilities.invokeLater(
            CrawlerRunnable(self.moveRegexDownButton.setEnabled, (True, )))
        SwingUtilities.invokeLater(
            CrawlerRunnable(self.removeRegexButton.setEnabled, (True, )))

        SwingUtilities.invokeLater(
            CrawlerRunnable(self.crawlStatusLabel.setText,
                            ("Ready to crawl", )))

        self.crawlingEvent.clear()
        print("Completed")
コード例 #10
0
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('<', '&lt;')
						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('<', '&lt;') + "</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()
コード例 #11
0
ファイル: hunt_methodology.py プロジェクト: nuryslyrt/HUNT
class View:
    def __init__(self):
        self.data = Data()
        self.checklist = self.data.get_checklist()
        self.issues = self.data.get_issues()

        self.set_checklist_tree()
        self.set_tree()
        self.set_pane()
        self.set_tabbed_panes()
        self.set_settings()

        self.set_tsl()

    def set_checklist(self, file_name):
        self.data.set_checklist(file_name)
        self.checklist = self.data.get_checklist()

    def get_checklist(self):
        return self.checklist

    def get_issues(self):
        return self.issues

    # TODO: Create the checklist dynamically for all nodes based on JSON structure
    # Creates a DefaultMutableTreeNode using the JSON file data
    def set_checklist_tree(self):
        self.checklist_tree = DefaultMutableTreeNode("HUNT - Methodology")

        for item in self.checklist:
            node = DefaultMutableTreeNode(item)
            self.checklist_tree.add(node)

            is_functionality = node.toString() == "Functionality"

            if is_functionality:
                functionality_node = node

        functionality = self.checklist["Functionality"]

        # TODO: Sort the functionality by name and by test name
        for functionality_name in functionality:
            tests = functionality[functionality_name]["tests"]
            node = DefaultMutableTreeNode(functionality_name)

            for test_name in tests:
                node.add(DefaultMutableTreeNode(test_name))

            functionality_node.add(node)

    def get_checklist_tree(self):
        return self.checklist_tree

    # Creates a JTree object from the checklist
    def set_tree(self):
        self.tree = JTree(self.checklist_tree)
        self.tree.getSelectionModel().setSelectionMode(
            TreeSelectionModel.SINGLE_TREE_SELECTION)

    def get_tree(self):
        return self.tree

    # TODO: Change to briefcase icon for brief, P1-P5 icons for vulns,
    #       bullseye icon for Targets, etc
    # Create a JSplitPlane with a JTree to the left and JTabbedPane to right
    def set_pane(self):
        status = JTextArea()
        status.setLineWrap(True)
        status.setText("Nothing selected")
        self.status = status

        self.pane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                               JScrollPane(self.tree), JTabbedPane())

        self.pane.setDividerLocation(310)
        self.pane.getLeftComponent().setMinimumSize(Dimension(310, 300))

    def get_pane(self):
        return self.pane

    # Creates the tabs dynamically using data from the JSON file
    def set_tabbed_panes(self):
        functionality = self.checklist["Functionality"]
        self.tabbed_panes = {}

        for functionality_name in functionality:
            tests = functionality[functionality_name]["tests"]

            for test_name in tests:
                key = functionality_name + "." + test_name
                tabbed_pane = self.set_tabbed_pane(functionality_name,
                                                   test_name)
                self.tabbed_panes[key] = self.tabbed_pane

    def get_tabbed_panes(self):
        return self.tabbed_panes

    # Creates a JTabbedPane for each vulnerability per functionality
    def set_tabbed_pane(self, functionality_name, test_name):
        description_tab = self.set_description_tab(functionality_name,
                                                   test_name)
        bugs_tab = self.set_bugs_tab()
        resources_tab = self.set_resource_tab(functionality_name, test_name)
        notes_tab = self.set_notes_tab()

        self.tabbed_pane = JTabbedPane()
        self.tabbed_pane.add("Description", description_tab)
        self.tabbed_pane.add("Bugs", bugs_tab)
        self.tabbed_pane.add("Resources", resources_tab)
        self.tabbed_pane.add("Notes", notes_tab)

    # Creates the description panel
    def set_description_tab(self, fn, vn):
        description_text = str(
            self.checklist["Functionality"][fn]["tests"][vn]["description"])
        description_textarea = JTextArea()
        description_textarea.setLineWrap(True)
        description_textarea.setText(description_text)
        description_panel = JScrollPane(description_textarea)

        return description_panel

    # TODO: Add functionality to remove tabs
    # Creates the bugs panel
    def set_bugs_tab(self):
        bugs_tab = JTabbedPane()

        return bugs_tab

    # Creates the resources panel
    def set_resource_tab(self, fn, vn):
        resource_urls = self.checklist["Functionality"][fn]["tests"][vn][
            "resources"]
        resource_text = ""

        for url in resource_urls:
            resource_text = resource_text + str(url) + "\n"

        resource_textarea = JTextArea()
        resource_textarea.setLineWrap(True)
        resource_textarea.setWrapStyleWord(True)
        resource_textarea.setText(resource_text)
        resources_panel = JScrollPane(resource_textarea)

        return resources_panel

    def set_notes_tab(self):
        notes_textarea = JTextArea()

        return notes_textarea

    def set_tsl(self):
        self.tsl = TSL(self)
        self.tree.addTreeSelectionListener(self.tsl)

        return

    def get_tsl(self):
        return self.tsl

    def set_settings(self):
        self.settings = JPanel()
        layout = GroupLayout(self.settings)
        self.settings.setLayout(layout)
        layout.setAutoCreateGaps(True)

        load_file_button = JButton("Load JSON File")
        load_file_button.setActionCommand("load")
        load_file_button.addActionListener(
            SettingsAction(self, load_file_button, None))
        save_file_button = JButton("Save JSON File")
        save_file_button.setActionCommand("save")
        save_file_button.addActionListener(
            SettingsAction(None, save_file_button, self.tabbed_panes))

        horizontal_group1 = layout.createParallelGroup(
            GroupLayout.Alignment.LEADING)
        horizontal_group1.addComponent(load_file_button)
        horizontal_group1.addComponent(save_file_button)

        horizontal_group = layout.createSequentialGroup()
        horizontal_group.addGroup(horizontal_group1)

        layout.setHorizontalGroup(horizontal_group)

        vertical_group1 = layout.createParallelGroup(
            GroupLayout.Alignment.BASELINE)
        vertical_group1.addComponent(load_file_button)
        vertical_group2 = layout.createParallelGroup(
            GroupLayout.Alignment.BASELINE)
        vertical_group2.addComponent(save_file_button)

        vertical_group = layout.createSequentialGroup()
        vertical_group.addGroup(vertical_group1)
        vertical_group.addGroup(vertical_group2)

        layout.setVerticalGroup(vertical_group)

    def get_settings(self):
        return self.settings

    def set_request_tab_pane(self, request_response):
        raw_request = request_response.getRequest()
        request_body = StringUtil.fromBytes(raw_request)
        request_body = request_body.encode("utf-8")

        request_tab_textarea = JTextArea(request_body)
        request_tab_textarea.setLineWrap(True)

        return JScrollPane(request_tab_textarea)

    def set_response_tab_pane(self, request_response):
        raw_response = request_response.getResponse()
        response_body = StringUtil.fromBytes(raw_response)
        response_body = response_body.encode("utf-8")

        response_tab_textarea = JTextArea(response_body)
        response_tab_textarea.setLineWrap(True)

        return JScrollPane(response_tab_textarea)

    def set_bugs_tabbed_pane(self, request_tab, response_tab):
        bugs_tabbed_pane = JTabbedPane()

        bugs_tabbed_pane.add("Request", request_tab)
        bugs_tabbed_pane.add("Response", response_tab)

        return bugs_tabbed_pane
コード例 #12
0
class AtfAreaView(JPanel):
    '''
    Initializes the ATF (edit/model) view and sets its layout.
    '''
    def __init__(self, controller):
        '''
        Creates default empty text area in a panel for ATF edition.
        It has syntax highlighting based on the ATF parser (pyoracc).
        It also highlights line numbers where there are validations errors
        returned by the ORACC server.
        '''
        # Give reference to controller to delegate action response
        self.controller = controller

        # Make text area occupy all available space and resize with parent
        # window
        self.setLayout(BorderLayout())

        # Short hand for edit area and line numbers area
        self.edit_area = self.controller.edit_area
        self.line_numbers_area = self.controller.line_numbers_area

        # Create secondary text area for split view
        self.secondary_area = self.controller.secondary_area
        self.secondary_line_numbers = self.controller.secondary_line_numbers

        # Set undo/redo manager to edit area
        self.undo_manager = UndoManager()
        self.undo_manager.limit = 3000
        self.edit_listener = AtfUndoableEditListener(self.undo_manager)
        self.edit_area.getDocument().addUndoableEditListener(
            self.edit_listener)

        # Sort out layout by synch-ing line numbers and text area and putting
        # only the text area in a scroll pane as indicated in the
        # TextLineNumber tutorial.
        self.edit_area.setPreferredSize(Dimension(1, 500))
        self.container = JScrollPane(self.edit_area)
        self.container.setRowHeaderView(self.line_numbers_area)
        self.add(self.container, BorderLayout.CENTER)

        self.vert_scroll = self.container.getVerticalScrollBar()
        self.vert_scroll.addAdjustmentListener(atfAreaAdjustmentListener(self))

        # Key listener that triggers syntax highlighting, etc. upon key release
        self.edit_area.addKeyListener(AtfAreaKeyListener(self))
        # Also needed in secondary area:
        self.secondary_area.addKeyListener(AtfAreaKeyListener(self))

        # Add a document listener to track changes to files
        docListener = atfAreaDocumentListener(self)
        self.edit_area.getDocument().addDocumentListener(docListener)

        # instance variable to store a record of the text contents prior to the
        # most recent change. Needed so that the different listeners can access
        # this to handle error line updating.
        self.oldtext = ''

    def toggle_split(self, split_orientation=None):
        '''
        Clear ATF edit area and repaint chosen layout (splitscreen/scrollpane).
        '''
        # Remove all existent components in parent JPanel
        self.removeAll()
        # Check what editor view to toggle
        self.setup_edit_area(split_orientation)
        # Revalitate is needed in order to repaint the components
        self.revalidate()
        self.repaint()

    def setup_edit_area(self, split_orientation=None):
        '''
        Check if the ATF text area is being displayed in a split editor.
        If so, resets to normal JScrollPane. If not, splits the screen.
        '''
        if isinstance(self.container, JSplitPane):
            # If Nammu is already displaying a split pane, reset to original
            # setup
            self.container = JScrollPane(self.edit_area)
            self.container.setRowHeaderView(self.line_numbers_area)
            self.container.setVisible(True)
            self.add(self.container, BorderLayout.CENTER)
        else:
            # If there is not a split pane, create both panels and setup view
            main_editor = JScrollPane(self.edit_area)
            main_editor.setRowHeaderView(self.line_numbers_area)
            secondary_editor = JScrollPane(self.secondary_area)
            secondary_editor.setRowHeaderView(self.secondary_line_numbers)
            self.container = JSplitPane(split_orientation, main_editor,
                                        secondary_editor)
            self.container.setDividerSize(5)
            self.container.setVisible(True)
            self.container.setDividerLocation(0.5)
            self.container.setResizeWeight(0.5)
            self.add(self.container, BorderLayout.CENTER)

    def get_viewport_carets(self):
        '''
        Get the top left and bottom left caret position of the current viewport
        '''
        extent = self.container.getViewport().getExtentSize()
        top_left_position = self.container.getViewport().getViewPosition()
        top_left_char = self.edit_area.viewToModel(top_left_position)
        bottom_left_position = Point(top_left_position.x,
                                     top_left_position.y + extent.height)
        bottom_left_char = self.edit_area.viewToModel(bottom_left_position)

        # Something has gone wrong. Assume that top_left should be at the start
        # of the file
        if top_left_char >= bottom_left_char:
            top_left_char = 0

        # Get the text in the full edit area
        text = self.controller.edit_area.getText()

        # Pad the top of the viewport to capture up to the nearest header and
        # the bottom by 2 lines
        top_ch = self.controller.pad_top_viewport_caret(top_left_char, text)
        bottom_ch = self.controller.pad_bottom_viewport_caret(
            bottom_left_char, text)

        return top_ch, bottom_ch

    def refresh(self):
        '''
        Restyle edit area using user selected appearance settings.
        '''

        config = self.controller.controller.config

        # Create a new font with the new size
        font = set_font(config['edit_area_style']['fontsize']['user'])

        # Update the sytnax highlighter font params, so our changes are not
        # superceded
        self.controller.syntax_highlighter.font = font
        self.controller.syntax_highlighter.setup_attribs()

        attrs = self.controller.edit_area.getInputAttributes()
        StyleConstants.setFontSize(attrs, font.getSize())

        # Get the Styledoc so we can update it
        doc = self.controller.edit_area.getStyledDocument()

        # Apply the new fontsize to the whole document
        doc.setCharacterAttributes(0, doc.getLength() + 1, attrs, False)
コード例 #13
0
ファイル: hunt_scanner.py プロジェクト: gazcbm/HUNT
class View:
    def __init__(self, issues):
        self.json = issues.get_json()
        self.issues_object = issues
        self.issues = issues.get_issues()
        self.scanner_issues = issues.get_scanner_issues()
        self.scanner_panes = {}
        self.scanner_table_models = {}
        self.scanner_tables = {}
        self.is_scanner_panes = []

        self.set_vuln_tree()
        self.set_tree()
        self.set_scanner_table_models()
        self.set_scanner_panes()
        self.set_pane()
        self.set_settings()
        self.set_tsl()

    def get_issues_object(self):
        return self.issues_object

    def set_callbacks(self, callbacks):
        self.callbacks = callbacks

    def set_helpers(self, helpers):
        self.helpers = helpers

    def get_helpers(self):
        return self.helpers

    def get_issues(self):
        return self.issues

    def get_scanner_issues(self):
        return self.scanner_issues

    def set_is_scanner_pane(self, scanner_pane):
        self.is_scanner_panes.append(scanner_pane)

    def get_is_scanner_pane(self, scanner_pane):
        for pane in self.get_is_scanner_panes():
            if pane == scanner_pane:
                return True

        return False

    def get_is_scanner_panes(self):
        return self.is_scanner_panes

    def set_vuln_tree(self):
        self.vuln_tree = DefaultMutableTreeNode("HUNT Scanner")

        vulns = self.json["issues"]

        # TODO: Sort the functionality by name and by vuln class
        for vuln_name in sorted(vulns):
            vuln = DefaultMutableTreeNode(vuln_name)
            self.vuln_tree.add(vuln)

            parameters = self.json["issues"][vuln_name]["params"]

            for parameter in sorted(parameters):
                param_node = DefaultMutableTreeNode(parameter)
                vuln.add(param_node)

        self.vuln_tree.add(DefaultMutableTreeNode("Settings"))

    # Creates a JTree object from the checklist
    def set_tree(self):
        self.tree = JTree(self.vuln_tree)
        self.tree.getSelectionModel().setSelectionMode(
            TreeSelectionModel.SINGLE_TREE_SELECTION)

    def get_tree(self):
        return self.tree

    def set_scanner_table_models(self):
        issues = self.issues

        for issue in issues:
            issue_name = issue["name"]
            issue_param = issue["param"]

            self.create_scanner_table_model(issue_name, issue_param)

    # Creates the tabs dynamically using data from the JSON file
    def set_scanner_panes(self):
        for issue in self.issues:
            issue_name = issue["name"]
            issue_param = issue["param"]
            key = issue_name + "." + issue_param

            top_pane = self.create_request_list_pane(issue_name)
            bottom_pane = self.create_tabbed_pane()

            scanner_pane = JSplitPane(JSplitPane.VERTICAL_SPLIT, top_pane,
                                      bottom_pane)
            self.scanner_panes[key] = scanner_pane

    def get_scanner_panes(self):
        return self.scanner_panes

    def create_request_list_pane(self, issue_name):
        request_list_pane = JScrollPane()

        return request_list_pane

    # Creates a JTabbedPane for each vulnerability per functionality
    def create_tabbed_pane(self):
        tabbed_pane = JTabbedPane()
        tabbed_pane.add("Advisory", JScrollPane())
        tabbed_pane.add("Request", JScrollPane())
        tabbed_pane.add("Response", JScrollPane())

        self.tabbed_pane = tabbed_pane

        return tabbed_pane

    def get_settings(self):
        return self.settings

    def set_settings(self):
        self.settings = JPanel()
        layout = GroupLayout(self.settings)
        self.settings.setLayout(layout)
        layout.setAutoCreateGaps(True)

        load_file_button = JButton("Load JSON File")
        load_file_button.setActionCommand("load")
        load_file_button.addActionListener(
            SettingsAction(self, load_file_button, None))
        save_file_button = JButton("Save JSON File")
        save_file_button.setActionCommand("save")
        save_file_button.addActionListener(
            SettingsAction(self, save_file_button, self.scanner_panes))

        horizontal_group1 = layout.createParallelGroup(
            GroupLayout.Alignment.LEADING)
        horizontal_group1.addComponent(load_file_button)
        horizontal_group1.addComponent(save_file_button)

        horizontal_group = layout.createSequentialGroup()
        horizontal_group.addGroup(horizontal_group1)

        layout.setHorizontalGroup(horizontal_group)

        vertical_group1 = layout.createParallelGroup(
            GroupLayout.Alignment.BASELINE)
        vertical_group1.addComponent(load_file_button)
        vertical_group2 = layout.createParallelGroup(
            GroupLayout.Alignment.BASELINE)
        vertical_group2.addComponent(save_file_button)

        vertical_group = layout.createSequentialGroup()
        vertical_group.addGroup(vertical_group1)
        vertical_group.addGroup(vertical_group2)

        layout.setVerticalGroup(vertical_group)

    def set_tsl(self):
        tsl = TSL(self)
        self.tree.addTreeSelectionListener(tsl)

        return

    def set_pane(self):
        status = JTextArea()
        status.setLineWrap(True)
        status.setText("Nothing selected")
        self.status = status

        request_list_pane = JScrollPane()
        scanner_pane = JSplitPane(JSplitPane.VERTICAL_SPLIT, request_list_pane,
                                  self.tabbed_pane)
        self.pane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                               JScrollPane(self.tree), scanner_pane)
        self.pane.setDividerLocation(310)
        self.pane.getLeftComponent().setMinimumSize(Dimension(310, 300))

    def get_pane(self):
        return self.pane

    # TODO: Move all scanner table functions into its own ScannerTable class
    #       as well as ScannerTableModel for all scanner table model functions
    def create_scanner_table_model(self, issue_name, issue_param):
        key = issue_name + "." + issue_param
        is_model_exists = key in self.scanner_table_models

        if is_model_exists:
            return

        scanner_table_model = ScannerTableModel()
        scanner_table_model.addColumn("")
        scanner_table_model.addColumn("Parameter")
        scanner_table_model.addColumn("Host")
        scanner_table_model.addColumn("Path")
        scanner_table_model.addColumn("ID")

        self.scanner_table_models[key] = scanner_table_model

    def set_scanner_table_model(self, scanner_issue, issue_name, issue_param,
                                vuln_param):
        key = issue_name + "." + vuln_param
        scanner_issue_id = str(
            scanner_issue.getRequestResponse()).split("@")[1]
        scanner_table_model = self.scanner_table_models[key]

        # Using the addRow() method requires that the data type being passed to be of type
        # Vector() or Object(). Passing a Python object of type list in addRow causes a type
        # conversion error of sorts which presents as an ArrayOutOfBoundsException. Therefore,
        # row is an instantiation of Object() to avoid this error.
        row = Object()
        row = [
            False, issue_param,
            scanner_issue.getHttpService().getHost(),
            scanner_issue.getPath(), scanner_issue_id
        ]
        scanner_table_model.addRow(row)

        # Wait for ScannerTableModel to update as to not get an ArrayOutOfBoundsException.
        Thread.sleep(500)

        scanner_table_model.fireTableDataChanged()
        scanner_table_model.fireTableStructureChanged()

    def get_scanner_table_model(self, issue_name, issue_param):
        key = issue_name + "." + issue_param
        return self.scanner_table_models[key]

    def set_scanner_pane(self, scanner_pane, issue_name, issue_param):
        key = issue_name + "." + issue_param
        request_table_pane = scanner_pane.getTopComponent()

        if key in self.scanner_tables:
            scanner_table = self.scanner_tables[key]
        else:
            scanner_table = self.create_scanner_table(scanner_pane, issue_name,
                                                      issue_param)
            self.scanner_tables[key] = scanner_table

        request_table_pane.getViewport().setView(scanner_table)
        request_table_pane.revalidate()
        request_table_pane.repaint()

    def create_scanner_table(self, scanner_pane, issue_name, issue_param):
        scanner_table_model = self.get_scanner_table_model(
            issue_name, issue_param)

        scanner_table = JTable(scanner_table_model)
        scanner_table.getColumnModel().getColumn(0).setMaxWidth(10)
        scanner_table.putClientProperty("terminateEditOnFocusLost", True)
        scanner_table_listener = ScannerTableListener(self, scanner_table,
                                                      issue_name, issue_param)
        scanner_table_model.addTableModelListener(scanner_table_listener)
        scanner_table_list_listener = IssueListener(self, scanner_table,
                                                    scanner_pane, issue_name,
                                                    issue_param)
        scanner_table.getSelectionModel().addListSelectionListener(
            scanner_table_list_listener)

        return scanner_table

    # Takes into account if there are more than one scanner issues that share the same hostname, path, name, param, and id
    def set_tabbed_pane(self, scanner_pane, request_list, issue_hostname,
                        issue_path, issue_name, issue_param, scanner_issue_id):
        tabbed_pane = scanner_pane.getBottomComponent()
        scanner_issues = self.get_scanner_issues()
        current_issue = self.set_current_issue(scanner_issues, issue_hostname,
                                               issue_path, issue_name,
                                               issue_param, scanner_issue_id)

        advisory_tab_pane = self.set_advisory_tab_pane(current_issue)
        tabbed_pane.setComponentAt(0, advisory_tab_pane)

        request_tab_pane = self.set_request_tab_pane(current_issue)
        tabbed_pane.setComponentAt(1, request_tab_pane)

        response_tab_pane = self.set_response_tab_pane(current_issue)
        tabbed_pane.setComponentAt(2, response_tab_pane)

    def set_current_issue(self, scanner_issues, issue_hostname, issue_path,
                          issue_name, issue_param, scanner_issue_id):
        for scanner_issue in scanner_issues:
            is_same_hostname = scanner_issue.getHostname() == issue_hostname
            is_same_path = scanner_issue.getPath() == issue_path
            is_same_name = scanner_issue.getIssueName() == issue_name
            is_same_param = scanner_issue.getParameter() == issue_param
            is_same_id = str(scanner_issue.getRequestResponse()).split(
                "@")[1] == scanner_issue_id
            is_same_issue = is_same_hostname and is_same_path and is_same_name and is_same_param and is_same_id

            if is_same_issue:
                return scanner_issue

    def set_advisory_tab_pane(self, scanner_issue):
        advisory_pane = JEditorPane()
        advisory_pane.setEditable(False)
        advisory_pane.setEnabled(True)
        advisory_pane.setContentType("text/html")
        link_listener = LinkListener()
        advisory_pane.addHyperlinkListener(link_listener)
        advisory = "<html><b>Location</b>: {}<br><br>{}</html>"
        advisory_pane.setText(
            advisory.format(scanner_issue.getUrl().encode("utf-8"),
                            scanner_issue.getIssueDetail()))

        return JScrollPane(advisory_pane)

    def set_request_tab_pane(self, scanner_issue):
        request_response = scanner_issue.getRequestResponse()
        controller = MessageController(request_response)
        message_editor = self.callbacks.createMessageEditor(controller, True)
        message_editor.setMessage(request_response.getRequest(), True)
        component = message_editor.getComponent()

        return component

    def set_response_tab_pane(self, scanner_issue):
        request_response = scanner_issue.getRequestResponse()
        controller = MessageController(request_response)
        message_editor = self.callbacks.createMessageEditor(controller, True)
        message_editor.setMessage(request_response.getResponse(), False)
        component = message_editor.getComponent()

        return component

    def traverse_tree(self, tree, model, issue_name, issue_param, issue_count,
                      total_count):
        root = model.getRoot()
        count = int(root.getChildCount())
        traverse = {}

        for i in range(count):
            node = model.getChild(root, i)
            traverse["node"] = node
            tree_issue_name = node.toString()

            is_issue_name = re.search(issue_name, tree_issue_name)

            if is_issue_name:
                child_count = node.getChildCount()

                for j in range(child_count):
                    child = node.getChildAt(j)
                    traverse["child"] = child
                    tree_param_name = child.toString()

                    is_param_name = re.search(issue_param, tree_param_name)

                    if is_param_name:
                        traverse["param_text"] = issue_param + " (" + str(
                            issue_count) + ")"
                        break

                traverse["issue_text"] = issue_name + " (" + str(
                    total_count) + ")"
                break

        return traverse

    def set_scanner_count(self, issue_name, issue_param, issue_count,
                          total_count):
        tree = self.get_tree()
        model = tree.getModel()
        traverse = self.traverse_tree(tree, model, issue_name, issue_param,
                                      issue_count, total_count)
        node = traverse["node"]
        child = traverse["child"]

        child.setUserObject(traverse["param_text"])
        model.nodeChanged(child)
        model.reload(node)

        node.setUserObject(traverse["issue_text"])
        model.nodeChanged(node)
        model.reload(node)
コード例 #14
0
class javadocInfo_10( java.lang.Runnable ) :

    #---------------------------------------------------------------------------
    # Name: __init__()
    # Role: Constructor - initialize application variables
    #---------------------------------------------------------------------------
    def __init__( self ) :
        self.prevText = None      # Previously specified user input (text)

    #---------------------------------------------------------------------------
    # Name: run()
    # Role: Instantiate the user class
    # Note: Invoked by the Swing Event Dispatch Thread
    #---------------------------------------------------------------------------
    def run( self ) :
        #-----------------------------------------------------------------------
        # Size the frame to use 1/2 of the screen
        #-----------------------------------------------------------------------
        screenSize = Toolkit.getDefaultToolkit().getScreenSize()
        frameSize  = Dimension( screenSize.width >> 1, screenSize.height >> 1 )
        frame = JFrame(
            'javadocInfo_10',
            size = frameSize,
            defaultCloseOperation = JFrame.EXIT_ON_CLOSE
        )
        #-----------------------------------------------------------------------
        # Reposition the frame to be in the center of the screen
        #-----------------------------------------------------------------------
        frame.setLocation(
            ( screenSize.width  - frameSize.width  ) >> 1,
            ( screenSize.height - frameSize.height ) >> 1
        )
        #-----------------------------------------------------------------------
        # Initialize the list to have exactly 1 element
        #-----------------------------------------------------------------------
        model = DefaultListModel()
        model.addElement( 'One moment please...' )
        self.List = JList(
            model,
            valueChanged  = self.pick,
            selectionMode = ListSelectionModel.SINGLE_SELECTION
        )
        #-----------------------------------------------------------------------
        # Put the List in a ScrollPane and place it in the middle of a pane
        #-----------------------------------------------------------------------
        pane = JPanel( layout = BorderLayout() )
        pane.add(
            JScrollPane(
                self.List,
                minimumSize = ( 300, 50 )
            ),
            BorderLayout.CENTER
        )
        #-----------------------------------------------------------------------
        # Add a TextField [for the URL of the selected entry] at the bottom
        #-----------------------------------------------------------------------
        self.text = JTextField(
            'Enter text...',
            caretUpdate = self.caretUpdate
        )
        pane.add( self.text, BorderLayout.SOUTH )
        #-----------------------------------------------------------------------
        # Add the pane and a scrollable TextArea to a SplitPane in the frame
        #-----------------------------------------------------------------------
        self.area = JEditorPane(
            'text/html',
            '<html><h3>Nothing selected</h3></html>',
            editable = 0
        )
        self.splitPane = JSplitPane(
            JSplitPane.HORIZONTAL_SPLIT,
            pane,
            self.area
        )
        self.splitPane.setDividerLocation( 234 )
        frame.add( self.splitPane )
        #-----------------------------------------------------------------------
        # Create a separate thread to locate & proces the remote URL
        #-----------------------------------------------------------------------
        self.Links   = {}    # Initialize the Links dictionary
        self.classes = None  # complete list of all classes found
        soupTask(
            self.List,       # The visible JList instance
            self.text,       # User input field
            JAVADOC_URL,     # Remote web page URL to be processed
            self.Links,      # Dictionary of links found
        ).execute()
        frame.setVisible( 1 )

    #---------------------------------------------------------------------------
    # Name: pick()
    # Role: ListSelectionListener event handler
    #---------------------------------------------------------------------------
    def pick( self, e ) :
        #-----------------------------------------------------------------------
        # Note: Ignore valueIsAdjusting events
        #-----------------------------------------------------------------------
        if not e.getValueIsAdjusting() :
            List  = self.List
            model = List.getModel()

            #---------------------------------------------------------------
            # Is a "valid" item selected?
            #---------------------------------------------------------------
            index = List.getSelectedIndex()
            if index > -1 :
                choice = model.elementAt( index )
                if self.Links.has_key( choice ) :
                    url = self.Links[ choice ]
                    headerTask( url, self.splitPane ).execute()
            else :
                message = 'Nothing selected'
                comp = self.splitPane.getRightComponent()
                Type = str( comp.getClass() ).split( '.' )[ -1 ]
                if Type == 'JEditorPane' :
                    comp.setText( '<html><h3>%s</h3></html>' % message )
                else :
                    area = JEditorPane(
                        'text/html',
                        '<html><h3>%s</h3></html>' % message,
                        editable = 0
                    )
                    self.splitPane.setRightComponent( area )

    #---------------------------------------------------------------------------
    # Name: caretUpdate()
    # Role: CaretListener event handler used to monitor JTextField for user input
    #---------------------------------------------------------------------------
    def caretUpdate( self, e ) :
        field = e.getSource()
        text  = field.getText()
        if self.prevText == None :
            self.prevText = text

        if self.classes == None :
            result = self.Links.keys()
            if len( result ) > 0 :
                result.sort()
                self.classes = result

        #-----------------------------------------------------------------------
        # Did the user just move the cursor, or did they change the text field?
        #-----------------------------------------------------------------------
        if text != self.prevText :
#           print 'dot: %2d  text: "%s"' % ( e.getDot(), text )
            model = DefaultListModel()
            items = [ item for item in self.classes if item.find( text ) > -1 ]
            if len( items ) > 0 :
                for item in items :
                    model.addElement( item )
            else :
                model.addElement( 'No matching classes found.' )
            self.List.setModel( model )
        self.prevText = text
コード例 #15
0
class AtfAreaView(JPanel):
    '''
    Initializes the ATF (edit/model) view and sets its layout.
    '''
    def __init__(self, controller):
        '''
        Creates default empty text area in a panel for ATF edition.
        It has syntax highlighting based on the ATF parser (pyoracc).
        It also highlights line numbers where there are validations errors
        returned by the ORACC server.
        '''
        # Give reference to controller to delegate action response
        self.controller = controller

        # Make text area occupy all available space and resize with parent
        # window
        self.setLayout(BorderLayout())

        # Short hand for edit area and line numbers area
        self.edit_area = self.controller.edit_area
        self.line_numbers_area = self.controller.line_numbers_area

        # Create secondary text area for split view
        self.secondary_area = self.controller.secondary_area
        self.secondary_line_numbers = self.controller.secondary_line_numbers

        # Set undo/redo manager to edit area
        self.undo_manager = UndoManager()
        self.undo_manager.limit = 3000
        self.edit_listener = AtfUndoableEditListener(self.undo_manager)
        self.edit_area.getDocument().addUndoableEditListener(
            self.edit_listener)

        # Sort out layout by synch-ing line numbers and text area and putting
        # only the text area in a scroll pane as indicated in the
        # TextLineNumber tutorial.
        self.edit_area.setPreferredSize(Dimension(1, 500))
        self.container = JScrollPane(self.edit_area)
        self.container.setRowHeaderView(self.line_numbers_area)
        self.add(self.container, BorderLayout.CENTER)

        # Key listener that triggers syntax highlighting, etc. upon key release
        self.edit_area.addKeyListener(AtfAreaKeyListener(self.controller))
        # Also needed in secondary area:
        self.secondary_area.addKeyListener(AtfAreaKeyListener(self.controller))

    def toggle_split(self, split_orientation=None):
        '''
        Clear ATF edit area and repaint chosen layout (splitscreen/scrollpane).
        '''
        # Remove all existent components in parent JPanel
        self.removeAll()
        # Check what editor view to toggle
        self.setup_edit_area(split_orientation)
        # Revalitate is needed in order to repaint the components
        self.revalidate()
        self.repaint()

    def setup_edit_area(self, split_orientation=None):
        '''
        Check if the ATF text area is being displayed in a split editor.
        If so, resets to normal JScrollPane. If not, splits the screen.
        '''
        if isinstance(self.container, JSplitPane):
            # If Nammu is already displaying a split pane, reset to original
            # setup
            self.container = JScrollPane(self.edit_area)
            self.container.setRowHeaderView(self.line_numbers_area)
            self.container.setVisible(True)
            self.add(self.container, BorderLayout.CENTER)
        else:
            # If there is not a split pane, create both panels and setup view
            main_editor = JScrollPane(self.edit_area)
            main_editor.setRowHeaderView(self.line_numbers_area)
            secondary_editor = JScrollPane(self.secondary_area)
            secondary_editor.setRowHeaderView(self.secondary_line_numbers)
            self.container = JSplitPane(split_orientation, main_editor,
                                        secondary_editor)
            self.container.setDividerSize(5)
            self.container.setVisible(True)
            self.container.setDividerLocation(0.5)
            self.container.setResizeWeight(0.5)
            self.add(self.container, BorderLayout.CENTER)
コード例 #16
0
    def __init__(self):
        #obtain prefixes from folder
        self.dict1 = self.obtain_prefixes(
        )  #Run prefix selection function - sets source directory, requests prefix size, outputs prefix dictionary
        lst = list(self.dict1.keys())  #pull prefixes only, as list
        self.lang = lst
        self.lst = JList(self.lang, valueChanged=self.listSelect
                         )  # pass prefix list to GUI selection list

        # general GUI layout parameters, no data processing here
        self.frame = JFrame("Image Selection")
        self.frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)
        self.frame.setLocation(100, 100)
        self.frame.setSize(800, 350)
        self.frame.setLayout(BorderLayout())

        self.frame.add(self.lst, BorderLayout.NORTH)
        self.lst.selectionMode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
        self.button1 = JButton('Select item(s)',
                               actionPerformed=self.clickhere)

        #Save option radio buttons and file extension selection
        #set main right panel (sub panels will fit within this)
        rightpanel = JPanel()
        rightpanel.setLayout(BoxLayout(rightpanel, BoxLayout.Y_AXIS))

        #set up savestate panel
        buttonpanel = JPanel()
        self.radiobutton1 = JRadioButton(
            "Open selected 3D stacks and max projections \n and save max projections",
            True)
        self.radiobutton2 = JRadioButton(
            "Open selected 3D stacks and max projections \n and DO NOT save max projections"
        )
        infoLabel = JLabel(
            "<html>Hold ctrl and click multiple prefixes to select multiple options. Will load stacks and MIPs separately <br><br> Type file extension in text field below:</html>",
            SwingConstants.LEFT)
        grp = ButtonGroup()
        grp.add(self.radiobutton1)
        grp.add(self.radiobutton2)
        #buttonpanel.setLayout(BoxLayout(buttonpanel, BoxLayout.Y_AXIS))
        buttonpanel.add(Box.createVerticalGlue())
        buttonpanel.add(infoLabel)
        buttonpanel.add(Box.createRigidArea(Dimension(0, 5)))
        buttonpanel.add(self.radiobutton1)
        buttonpanel.add(Box.createRigidArea(Dimension(0, 5)))
        buttonpanel.add(self.radiobutton2)

        #file extension instruction panel
        infopanel = JPanel()
        infopanel.setLayout(FlowLayout(FlowLayout.LEFT))
        infopanel.setMaximumSize(
            infopanel.setPreferredSize(Dimension(650, 100)))
        infopanel.add(infoLabel)

        #file extension input
        inputPanel = JPanel()
        inputPanel.setLayout(BoxLayout(inputPanel, BoxLayout.X_AXIS))
        self.filetype = JTextField(".tif", 15)
        self.filetype.setMaximumSize(self.filetype.getPreferredSize())
        inputPanel.add(self.filetype)

        ########### WIP - integrate prefix selection with main pane, with dynamically updating prefix list
        ##infoLabel3 = JLabel("how long is the file prefix to group by?(integer value only)")
        ##self.prefix_init = JTextField()
        ##buttonpanel.add(infoLabel3)
        ##buttonpanel.add(self.prefix_init)
        ########### !WIP
        #add file extension and savestate panels to main panel
        rightpanel.add(infopanel)
        rightpanel.add(inputPanel)
        rightpanel.add(buttonpanel, BorderLayout.EAST)

        #split list and radiobutton pane (construct overall window)
        spl = JSplitPane(JSplitPane.HORIZONTAL_SPLIT)
        spl.leftComponent = JScrollPane(self.lst)
        spl.setDividerLocation(150)
        spl.rightComponent = rightpanel
        self.frame.add(spl)
        self.frame.add(self.button1, BorderLayout.SOUTH)

        # GUI layout done, initialise GUI to select prefixes, file extension and save option
        self.frame.setVisible(True)
コード例 #17
0
 def dividerLocation(self, location):
     JSplitPane.setDividerLocation(self, location)
     newAuxPanelSize = self.flipLocation(location)
     if newAuxPanelSize >= self.minAuxSize):
         self.auxPanelVisibleSize = newAuxPanelSize
コード例 #18
0
    def __init__(self, ui):
        JSplitPane.__init__(self, JSplitPane.HORIZONTAL_SPLIT)
        self._ui = ui

        # create the executor object
        self._executor = Executor(self, ui.callbacks)

        ####
        # start Left Top split layout
        jLeftTopPanel = JPanel()
        jMenuPanel = JPanel()

        #Load button
        self.jLoad = JButton(Strings.jLoad_text)
        self.jLoad.addActionListener(self)
        #File name text field
        self.jFileName = JTextField(Strings.jFileName_default, 30)
        self.jFileName.setHorizontalAlignment(JTextField.CENTER)
        self.jFileName.setEditable(False)
        #Save button
        self.jSave = JButton(Strings.jSave_text)
        self.jSave.addActionListener(self)
        #Exit button
        self.jExit = JButton(Strings.jExit_text)
        self.jExit.addActionListener(self)
        #Wiki button (URL)
        self.jWiki = JButton(Strings.jWiki_title)
        self.jWiki.setToolTipText(Strings.jWiki_tooltip)
        self.jWiki.addActionListener(self)
        # make it borderless
        self.jWiki.setBorder(EmptyBorder(0, 0, 0, 0))
        self.jWiki.setBorderPainted(False)
        self.jWiki.setContentAreaFilled(False)

        #Console text area
        jConsoleText = JTextArea()
        jConsoleText.setEditable(0)
        jConsoleText.setWrapStyleWord(1)
        jConsoleText.setRows(10)
        #set initial text
        jConsoleText.setText(Strings.jConsoleText_help)
        #make scrollable
        jScrollConsolePane = JScrollPane()
        jScrollConsolePane.setViewportView(jConsoleText)

        jMenuPanelLayout = GroupLayout(jMenuPanel)
        jMenuPanel.setLayout(jMenuPanelLayout)
        jMenuPanelLayout.setHorizontalGroup(
            jMenuPanelLayout.createParallelGroup(
                GroupLayout.Alignment.LEADING).
            addGroup(jMenuPanelLayout.createSequentialGroup().addContainerGap(
            ).addComponent(self.jLoad).addComponent(
                self.jFileName).addPreferredGap(
                    LayoutStyle.ComponentPlacement.RELATED).addComponent(
                        self.jSave).addPreferredGap(
                            LayoutStyle.ComponentPlacement.RELATED).
                     addComponent(self.jWiki).addPreferredGap(
                         LayoutStyle.ComponentPlacement.RELATED).addComponent(
                             self.jExit).addContainerGap()))
        jMenuPanelLayout.setVerticalGroup(
            jMenuPanelLayout.createParallelGroup(
                GroupLayout.Alignment.LEADING).addGroup(
                    jMenuPanelLayout.createSequentialGroup().addGroup(
                        jMenuPanelLayout.createParallelGroup(
                            GroupLayout.Alignment.BASELINE).addComponent(
                                self.jLoad).addComponent(
                                    self.jFileName, GroupLayout.PREFERRED_SIZE,
                                    GroupLayout.DEFAULT_SIZE,
                                    GroupLayout.PREFERRED_SIZE).addComponent(
                                        self.jSave).addComponent(
                                            self.jWiki).addComponent(
                                                self.jExit))))

        jLeftTopPanelLayout = GroupLayout(jLeftTopPanel)
        jLeftTopPanel.setLayout(jLeftTopPanelLayout)
        jLeftTopPanelLayout.setHorizontalGroup(
            jLeftTopPanelLayout.createParallelGroup(
                GroupLayout.Alignment.LEADING).addComponent(
                    jMenuPanel, GroupLayout.DEFAULT_SIZE,
                    GroupLayout.DEFAULT_SIZE,
                    GroupLayout.DEFAULT_SIZE).addComponent(
                        jScrollConsolePane, GroupLayout.DEFAULT_SIZE,
                        GroupLayout.DEFAULT_SIZE, 32767))
        jLeftTopPanelLayout.setVerticalGroup(
            jLeftTopPanelLayout.
            createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
                GroupLayout.Alignment.TRAILING,
                jLeftTopPanelLayout.createSequentialGroup().addComponent(
                    jMenuPanel, GroupLayout.PREFERRED_SIZE,
                    GroupLayout.DEFAULT_SIZE,
                    GroupLayout.PREFERRED_SIZE).addPreferredGap(
                        LayoutStyle.ComponentPlacement.RELATED).addComponent(
                            jScrollConsolePane, GroupLayout.DEFAULT_SIZE,
                            GroupLayout.DEFAULT_SIZE, 32767)))
        # end Left Top split layout
        ####

        ####
        # start Left Down split layout
        jLeftDownPanel = JPanel()
        jMenu2Panel = JPanel()

        #Clear button
        self.jClear = JButton(Strings.jClear_text)
        self.jClear.setToolTipText(Strings.jClear_tooltip)
        self.jClear.addActionListener(self)

        #Run button
        self.jRun = JButton(Strings.jRun_text)
        self.jRun.setToolTipText(Strings.jRun_tooltip)
        self.jRun.addActionListener(self)

        #Variables text area
        jVarsPane = JTextPane()
        jVarsPane.setFont(Font('Monospaced', Font.PLAIN, 11))
        jVarsPane.addFocusListener(self)
        # set initial value
        jVarsPane.setText(Strings.jVarsPane_header)
        # make scrollable
        jScrollpaneLeftDown = JScrollPane()
        jScrollpaneLeftDown.setViewportView(jVarsPane)

        jMenu2PanelLayout = GroupLayout(jMenu2Panel)
        jMenu2Panel.setLayout(jMenu2PanelLayout)
        jMenu2PanelLayout.setHorizontalGroup(
            jMenu2PanelLayout.createParallelGroup(
                GroupLayout.Alignment.LEADING).addGroup(
                    jMenu2PanelLayout.createSequentialGroup().addContainerGap(
                    ).addComponent(self.jClear).addPreferredGap(
                        LayoutStyle.ComponentPlacement.RELATED, 100,
                        32767).addComponent(self.jRun).addContainerGap()))
        jMenu2PanelLayout.setVerticalGroup(
            jMenu2PanelLayout.createParallelGroup(
                GroupLayout.Alignment.LEADING).addGroup(
                    jMenu2PanelLayout.createSequentialGroup().addGroup(
                        jMenu2PanelLayout.createParallelGroup(
                            GroupLayout.Alignment.BASELINE).addComponent(
                                self.jClear).addComponent(self.jRun))))
        jLeftDownPanelLayout = GroupLayout(jLeftDownPanel)
        jLeftDownPanel.setLayout(jLeftDownPanelLayout)
        jLeftDownPanelLayout.setHorizontalGroup(
            jLeftDownPanelLayout.createParallelGroup(
                GroupLayout.Alignment.LEADING).addComponent(
                    jMenu2Panel, GroupLayout.DEFAULT_SIZE,
                    GroupLayout.DEFAULT_SIZE,
                    GroupLayout.DEFAULT_SIZE).addComponent(
                        jScrollpaneLeftDown, GroupLayout.DEFAULT_SIZE,
                        GroupLayout.DEFAULT_SIZE, 32767))
        jLeftDownPanelLayout.setVerticalGroup(
            jLeftDownPanelLayout.
            createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(
                GroupLayout.Alignment.TRAILING,
                jLeftDownPanelLayout.createSequentialGroup().addComponent(
                    jMenu2Panel, GroupLayout.PREFERRED_SIZE,
                    GroupLayout.DEFAULT_SIZE,
                    GroupLayout.PREFERRED_SIZE).addPreferredGap(
                        LayoutStyle.ComponentPlacement.RELATED).addComponent(
                            jScrollpaneLeftDown, GroupLayout.DEFAULT_SIZE,
                            GroupLayout.DEFAULT_SIZE, 32767)))
        # end Left Down split layout
        ####

        ####
        # start Left layout
        jSplitPaneLeft = JSplitPane(JSplitPane.VERTICAL_SPLIT, jLeftTopPanel,
                                    jLeftDownPanel)
        jSplitPaneLeft.setDividerLocation(300)
        # end Left layout
        ####

        ####
        # start Right layout
        jScriptPane = JTextPane()
        jScriptPane.setFont(Font('Monospaced', Font.PLAIN, 11))
        # set initial value
        jScriptPane.setText(Strings.jScriptPane_header)
        #jScriptPane.addMouseListener(self)

        jScrollPaneRight = JScrollPane()
        jScrollPaneRight.setViewportView(jScriptPane)
        # end Right layout
        ####

        self.setLeftComponent(jSplitPaneLeft)
        self.setRightComponent(jScrollPaneRight)
        self.setDividerLocation(450)

        #Exported variables
        self.jConsoleText = jConsoleText
        self.jScrollConsolePane = jScrollConsolePane
        self.jScriptPane = jScriptPane
        self.jVarsPane = jVarsPane
コード例 #19
0
ファイル: AtfAreaView.py プロジェクト: oracc/nammu
class AtfAreaView(JPanel):
    '''
    Initializes the ATF (edit/model) view and sets its layout.
    '''
    def __init__(self, controller):
        '''
        Creates default empty text area in a panel for ATF edition.
        It has syntax highlighting based on the ATF parser (pyoracc).
        It also highlights line numbers where there are validations errors
        returned by the ORACC server.
        '''
        # Give reference to controller to delegate action response
        self.controller = controller

        # Make text area occupy all available space and resize with parent
        # window
        self.setLayout(BorderLayout())

        # Short hand for edit area and line numbers area
        self.edit_area = self.controller.edit_area
        self.line_numbers_area = self.controller.line_numbers_area

        # Create secondary text area for split view
        self.secondary_area = self.controller.secondary_area
        self.secondary_line_numbers = self.controller.secondary_line_numbers

        # Set undo/redo manager to edit area
        self.undo_manager = UndoManager()
        self.undo_manager.limit = 3000
        self.edit_listener = AtfUndoableEditListener(self.undo_manager)
        self.edit_area.getDocument().addUndoableEditListener(
                                                        self.edit_listener)

        # Sort out layout by synch-ing line numbers and text area and putting
        # only the text area in a scroll pane as indicated in the
        # TextLineNumber tutorial.
        self.edit_area.setPreferredSize(Dimension(1, 500))
        self.container = JScrollPane(self.edit_area)
        self.container.setRowHeaderView(self.line_numbers_area)
        self.add(self.container, BorderLayout.CENTER)

        self.vert_scroll = self.container.getVerticalScrollBar()
        self.vert_scroll.addAdjustmentListener(atfAreaAdjustmentListener(self))

        # Key listener that triggers syntax highlighting, etc. upon key release
        self.edit_area.addKeyListener(AtfAreaKeyListener(self))
        # Also needed in secondary area:
        self.secondary_area.addKeyListener(AtfAreaKeyListener(self))

        # Add a document listener to track changes to files
        docListener = atfAreaDocumentListener(self)
        self.edit_area.getDocument().addDocumentListener(docListener)

        # instance variable to store a record of the text contents prior to the
        # most recent change. Needed so that the different listeners can access
        # this to handle error line updating.
        self.oldtext = ''

    def toggle_split(self, split_orientation=None):
        '''
        Clear ATF edit area and repaint chosen layout (splitscreen/scrollpane).
        '''
        # Remove all existent components in parent JPanel
        self.removeAll()
        # Check what editor view to toggle
        self.setup_edit_area(split_orientation)
        # Revalitate is needed in order to repaint the components
        self.revalidate()
        self.repaint()

    def setup_edit_area(self, split_orientation=None):
        '''
        Check if the ATF text area is being displayed in a split editor.
        If so, resets to normal JScrollPane. If not, splits the screen.
        '''
        if isinstance(self.container, JSplitPane):
            # If Nammu is already displaying a split pane, reset to original
            # setup
            self.container = JScrollPane(self.edit_area)
            self.container.setRowHeaderView(self.line_numbers_area)
            self.container.setVisible(True)
            self.add(self.container, BorderLayout.CENTER)
        else:
            # If there is not a split pane, create both panels and setup view
            main_editor = JScrollPane(self.edit_area)
            main_editor.setRowHeaderView(self.line_numbers_area)
            secondary_editor = JScrollPane(self.secondary_area)
            secondary_editor.setRowHeaderView(self.secondary_line_numbers)
            self.container = JSplitPane(split_orientation,
                                        main_editor,
                                        secondary_editor)
            self.container.setDividerSize(5)
            self.container.setVisible(True)
            self.container.setDividerLocation(0.5)
            self.container.setResizeWeight(0.5)
            self.add(self.container, BorderLayout.CENTER)

    def get_viewport_carets(self):
        '''
        Get the top left and bottom left caret position of the current viewport
        '''
        extent = self.container.getViewport().getExtentSize()
        top_left_position = self.container.getViewport().getViewPosition()
        top_left_char = self.edit_area.viewToModel(top_left_position)
        bottom_left_position = Point(top_left_position.x,
                                     top_left_position.y + extent.height)
        bottom_left_char = self.edit_area.viewToModel(bottom_left_position)

        # Something has gone wrong. Assume that top_left should be at the start
        # of the file
        if top_left_char >= bottom_left_char:
            top_left_char = 0

        # Get the text in the full edit area
        text = self.controller.edit_area.getText()

        # Pad the top of the viewport to capture up to the nearest header and
        # the bottom by 2 lines
        top_ch = self.controller.pad_top_viewport_caret(top_left_char, text)
        bottom_ch = self.controller.pad_bottom_viewport_caret(bottom_left_char,
                                                              text)

        return top_ch, bottom_ch

    def refresh(self):
        '''
        Restyle edit area using user selected appearance settings.
        '''

        config = self.controller.controller.config

        # Create a new font with the new size
        font = set_font(config['edit_area_style']['fontsize']['user'])

        # Update the sytnax highlighter font params, so our changes are not
        # superceded
        self.controller.syntax_highlighter.font = font
        self.controller.syntax_highlighter.setup_attribs()

        attrs = self.controller.edit_area.getInputAttributes()
        StyleConstants.setFontSize(attrs, font.getSize())

        # Get the Styledoc so we can update it
        doc = self.controller.edit_area.getStyledDocument()

        # Apply the new fontsize to the whole document
        doc.setCharacterAttributes(0, doc.getLength() + 1, attrs, False)
コード例 #20
0
class View:
    def __init__(self, issues):
        self.json = issues.get_json()
        self.issues_object = issues
        self.issues = issues.get_issues()
        self.scanner_issues = issues.get_scanner_issues()
        self.scanner_panes = {}
        self.scanner_tables = {}
        self.is_scanner_panes = []

        self.set_vuln_tree()
        self.set_tree()
        self.set_scanner_panes()
        self.set_pane()
        self.set_tsl()

    def set_callbacks(self, callbacks):
        self.callbacks = callbacks

    def set_helpers(self, helpers):
        self.helpers = helpers

    def get_helpers(self):
        return self.helpers

    def get_issues(self):
        return self.issues

    def get_scanner_issues(self):
        return self.scanner_issues

    def set_scanner_count(self, is_checked, issue_name, issue_param):
        self.issues_object.set_scanner_count(self, is_checked, issue_name, issue_param)

    def set_is_scanner_pane(self, scanner_pane):
        self.is_scanner_panes.append(scanner_pane)

    def get_is_scanner_pane(self, scanner_pane):
        for pane in self.get_is_scanner_panes():
            if pane == scanner_pane:
                return True

        return False

    def get_is_scanner_panes(self):
        return self.is_scanner_panes

    def set_vuln_tree(self):
        self.vuln_tree = DefaultMutableTreeNode("Vulnerability Classes")

        vulns = self.json["issues"]

        # TODO: Sort the functionality by name and by vuln class
        for vuln_name in vulns:
            vuln = DefaultMutableTreeNode(vuln_name)
            self.vuln_tree.add(vuln)

            parameters = self.json["issues"][vuln_name]["params"]

            for parameter in parameters:
                param_node = DefaultMutableTreeNode(parameter)
                vuln.add(param_node)

    # Creates a JTree object from the checklist
    def set_tree(self):
        self.tree = JTree(self.vuln_tree)
        self.tree.getSelectionModel().setSelectionMode(
            TreeSelectionModel.SINGLE_TREE_SELECTION
        )

    def get_tree(self):
        return self.tree

    # Creates the tabs dynamically using data from the JSON file
    def set_scanner_panes(self):
        issues = self.issues

        for issue in issues:
            issue_name = issue["name"]
            issue_param = issue["param"]

            key = issue_name + "." + issue_param

            top_pane = self.create_request_list_pane(issue_name)
            bottom_pane = self.create_tabbed_pane()

            scanner_pane = JSplitPane(JSplitPane.VERTICAL_SPLIT, top_pane, bottom_pane)

            self.scanner_panes[key] = scanner_pane

    def get_scanner_panes(self):
        return self.scanner_panes

    def create_request_list_pane(self, issue_name):
        request_list_pane = JScrollPane()

        return request_list_pane

    # Creates a JTabbedPane for each vulnerability per functionality
    def create_tabbed_pane(self):
        tabbed_pane = JTabbedPane()
        tabbed_pane.add("Advisory", JScrollPane())
        tabbed_pane.add("Request", JScrollPane())
        tabbed_pane.add("Response", JScrollPane())

        self.tabbed_pane = tabbed_pane

        return tabbed_pane

    def set_tsl(self):
        tsl = TSL(self)
        self.tree.addTreeSelectionListener(tsl)

        return

    def set_pane(self):
        status = JTextArea()
        status.setLineWrap(True)
        status.setText("Nothing selected")
        self.status = status

        request_list_pane = JScrollPane()

        scanner_pane = JSplitPane(JSplitPane.VERTICAL_SPLIT,
                       request_list_pane,
                       self.tabbed_pane
        )

        self.pane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                    JScrollPane(self.tree),
                    scanner_pane
        )

        self.pane.setDividerLocation(310)
        self.pane.getLeftComponent().setMinimumSize(Dimension(310, 300))

    def get_pane(self):
        return self.pane

    def set_scanner_table(self, scanner_pane, scanner_table):
        self.scanner_tables[scanner_pane] = scanner_table

    def get_scanner_table(self, scanner_pane):
        return self.scanner_tables[scanner_pane]

    def set_scanner_pane(self, scanner_pane):
        request_table_pane = scanner_pane.getTopComponent()
        scanner_table = self.get_scanner_table(scanner_pane)

        request_table_pane.getViewport().setView(scanner_table)
        request_table_pane.revalidate()
        request_table_pane.repaint()

    def create_scanner_pane(self, scanner_pane, issue_name, issue_param):
        scanner_issues = self.get_scanner_issues()
        request_table_pane = scanner_pane.getTopComponent()

        scanner_table_model = ScannerTableModel()
        scanner_table_model.addColumn("Checked")
        scanner_table_model.addColumn("Host")
        scanner_table_model.addColumn("Path")

        # Search all issues for the correct issue. Once found, add it into
        # the scanner table model to be showed in the UI.
        for scanner_issue in scanner_issues:
            is_same_name = scanner_issue.getIssueName() == issue_name
            is_same_param = scanner_issue.getParameter() == issue_param
            is_same_issue = is_same_name and is_same_param

            if is_same_issue:
                scanner_table_model.addRow([
                    False,
                    scanner_issue.getHttpService().getHost(),
                    scanner_issue.getUrl()
                ])

        scanner_table = JTable(scanner_table_model)
        scanner_table.getColumnModel().getColumn(0).setCellEditor(DefaultCellEditor(JCheckBox()))
        scanner_table.putClientProperty("terminateEditOnFocusLost", True)
        scanner_table_listener = ScannerTableListener(self, scanner_table, issue_name, issue_param)
        scanner_table_model.addTableModelListener(scanner_table_listener)
        scanner_table_list_listener = IssueListener(self, scanner_table, scanner_pane, issue_name, issue_param)
        scanner_table.getSelectionModel().addListSelectionListener(scanner_table_list_listener)

        self.set_scanner_table(scanner_pane, scanner_table)

        request_table_pane.getViewport().setView(scanner_table)
        request_table_pane.revalidate()
        request_table_pane.repaint()

    def set_tabbed_pane(self, scanner_pane, request_list, issue_url, issue_name, issue_param):
        tabbed_pane = scanner_pane.getBottomComponent()
        scanner_issues = self.get_scanner_issues()

        for scanner_issue in scanner_issues:
            is_same_url = scanner_issue.getUrl() == issue_url
            is_same_name = scanner_issue.getIssueName() == issue_name
            is_same_param = scanner_issue.getParameter() == issue_param
            is_same_issue = is_same_url and is_same_name and is_same_param

            if is_same_issue:
                current_issue = scanner_issue
                self.set_context_menu(request_list, scanner_issue)
                break

        advisory_tab_pane = self.set_advisory_tab_pane(current_issue)
        tabbed_pane.setComponentAt(0, advisory_tab_pane)

        request_tab_pane = self.set_request_tab_pane(current_issue)
        tabbed_pane.setComponentAt(1, request_tab_pane)

        response_tab_pane = self.set_response_tab_pane(current_issue)
        tabbed_pane.setComponentAt(2, response_tab_pane)

    def set_advisory_tab_pane(self, scanner_issue):
        advisory_pane = JEditorPane()
        advisory_pane.setEditable(False)
        advisory_pane.setEnabled(True)
        advisory_pane.setContentType("text/html")
        link_listener = LinkListener()
        advisory_pane.addHyperlinkListener(link_listener)
        advisory_pane.setText("<html>" +
            "<b>Location</b>: " + scanner_issue.getUrl() + "<br><br>" +
            scanner_issue.getIssueDetail() + "</html>"
        )

        # Set a context menu
        self.set_context_menu(advisory_pane, scanner_issue)

        return JScrollPane(advisory_pane)

    def set_request_tab_pane(self, scanner_issue):
        raw_request = scanner_issue.getRequestResponse().getRequest()
        request_body = StringUtil.fromBytes(raw_request)
        request_body = request_body.encode("utf-8")

        request_tab_textarea = JTextArea(request_body)
        request_tab_textarea.setLineWrap(True)

        # Set a context menu
        self.set_context_menu(request_tab_textarea, scanner_issue)

        return JScrollPane(request_tab_textarea)

    def set_response_tab_pane(self, scanner_issue):
        raw_response = scanner_issue.getRequestResponse().getResponse()
        response_body = StringUtil.fromBytes(raw_response)
        response_body = response_body.encode("utf-8")

        response_tab_textarea = JTextArea(response_body)
        response_tab_textarea.setLineWrap(True)

        # Set a context menu
        self.set_context_menu(response_tab_textarea, scanner_issue)

        return JScrollPane(response_tab_textarea)

    # Pass scanner_issue as argument
    def set_context_menu(self, component, scanner_issue):
        self.context_menu = JPopupMenu()

        repeater = JMenuItem("Send to Repeater")
        repeater.addActionListener(PopupListener(scanner_issue, self.callbacks))

        intruder = JMenuItem("Send to Intruder")
        intruder.addActionListener(PopupListener(scanner_issue, self.callbacks))

        hunt = JMenuItem("Send to HUNT")

        self.context_menu.add(repeater)
        self.context_menu.add(intruder)

        context_menu_listener = ContextMenuListener(component, self.context_menu)
        component.addMouseListener(context_menu_listener)

    def get_context_menu(self):
        return self.context_menu
コード例 #21
0
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
コード例 #22
0
ファイル: mpconfig.py プロジェクト: DMDhariya/core
    def __init__(self,
                 kconfig_file="Kconfig",
                 config_file=".config",
                 systemLogger=None):
        """[summary]

        Parameters
        ----------
            kconfig_file : string (default: "Kconfig")
                The Kconfig configuration file
            config_file : string (default: ".config")
                The save file which will be used for loading and saving the settings
            systemLogger (default: None)
                A system logger object. If None then print statements are used for logging.
        """
        global log
        if systemLogger:
            log = systemLogger

        # Load Kconfig configuration files
        self.kconfig = Kconfig(kconfig_file)
        setKConfig(self.kconfig)

        if os.path.isfile(config_file):
            log.info(self.kconfig.load_config(config_file))
        elif os.path.isfile(".config"):
            log.info(self.kconfig.load_config(".config"))

        self.tree = KConfigTree(self.kconfig)
        self.tree.addTreeSelectionListener(self.treeSelectionChanged)
        jTreeSP = JScrollPane(self.tree)

        self.jta = JTextArea()
        self.jta.setEditable(False)
        jTextSP = JScrollPane(self.jta)

        toolPanel = JPanel()
        toolPanel.setLayout(BoxLayout(toolPanel, BoxLayout.X_AXIS))
        toolPanel.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0))

        toolPanel.add(JLabel("Search: "))

        jSearchPanel = JPanel()
        jSearchPanel.setLayout(BoxLayout(jSearchPanel, BoxLayout.X_AXIS))
        self.jSearchField = JTextField()
        jSearchPanel.setBackground(self.jSearchField.getBackground())
        jSearchPanel.setBorder(self.jSearchField.getBorder())
        self.jSearchField.setBorder(None)
        self.jSearchField.getDocument().addDocumentListener(
            SearchListener(self.tree))
        jSearchPanel.add(self.jSearchField)

        clearSearchButton = JButton(u'\u00d7',
                                    actionPerformed=self.clearSearch)
        d = clearSearchButton.getPreferredSize()
        clearSearchButton.setPreferredSize(Dimension(d.height, d.height))
        clearSearchButton.setBackground(self.jSearchField.getBackground())
        clearSearchButton.setBorder(None)
        clearSearchButton.setOpaque(False)
        clearSearchButton.setContentAreaFilled(False)
        clearSearchButton.setFocusPainted(False)
        jSearchPanel.add(clearSearchButton)

        toolPanel.add(jSearchPanel)

        self.showAllCheckBox = JCheckBox("Show all",
                                         actionPerformed=self.OnShowAllCheck)
        toolPanel.add(self.showAllCheckBox)

        splitPane = JSplitPane(JSplitPane.VERTICAL_SPLIT, jTreeSP, jTextSP)
        splitPane.setOneTouchExpandable(True)
        splitPane.setDividerLocation(300)

        treePanel = JPanel(BorderLayout())
        treePanel.add(toolPanel, BorderLayout.NORTH)
        treePanel.add(splitPane, BorderLayout.CENTER)

        loadSavePanel = JPanel()
        loadSavePanel.setLayout(BoxLayout(loadSavePanel, BoxLayout.X_AXIS))
        loadSavePanel.add(
            JButton("Load", actionPerformed=self.loadConfigDialog))
        loadSavePanel.add(
            JButton("Save as", actionPerformed=self.writeConfigDialog))

        self.rootPanel = JPanel()
        self.rootPanel.setLayout(BorderLayout())
        self.rootPanel.add(loadSavePanel, BorderLayout.PAGE_START)
        self.rootPanel.add(treePanel, BorderLayout.CENTER)
コード例 #23
0
class BurpExtender(IBurpExtender, IContextMenuFactory, ITab, IHttpListener, IMessageEditorController, AbstractTableModel):
    def registerExtenderCallbacks(self, callbacks):
        self.messages = []

        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        self._callbacks.setExtensionName('TPLogScan')

        self._log = ArrayList()
        self._lock = Lock()

        self.jSplitPaneV = JSplitPane(JSplitPane.VERTICAL_SPLIT, True)
        self.jSplitPaneV.setDividerLocation(300)
        self.jSplitPaneV.setOneTouchExpandable(True)

        self.jPanel_top = JPanel()
        self.jTabbedPane = JTabbedPane(JTabbedPane.TOP)

        self.iRequestTextEditor = self._callbacks.createMessageEditor(self, False)
        self.iResponseTextEditor = self._callbacks.createMessageEditor(self, False)

        self.jTable = CustomTable(self)
        self.jTable.setShowGrid(True)
        self.jTable.setAutoCreateRowSorter(True)
        self.jTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS)

        first_column_model = self.jTable.getColumnModel().getColumn(0)
        first_column_model.setPreferredWidth(60);
        first_column_model.setMaxWidth(60)
        first_column_model.setMinWidth(60)
        self.jTable.getColumnModel().getColumn(1).setPreferredWidth(300)

        third_column_model = self.jTable.getColumnModel().getColumn(2)
        third_column_model.setPreferredWidth(100)
        third_column_model.setMinWidth(100)
        self.jTable.getColumnModel().getColumn(3).setPreferredWidth(600)
        self.jTable.getColumnModel().getColumn(4).setPreferredWidth(100)
        self.jTable.getColumnModel().getColumn(5).setPreferredWidth(100)

        self.jScrollPane1 = JScrollPane(self.jTable)
        self.jScrollPane1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED)
        self.jScrollPane1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED)

        self.jTabbedPane.addTab("Log", self.jScrollPane1)

        self.jPanel_top.add(self.jTabbedPane)
        self.jPanel_top.setLayout(GridLayout(1,1))

        self.jSplitPaneInfo = JSplitPane(JSplitPane.HORIZONTAL_SPLIT, True)
        self.jSplitPaneInfo.setDividerLocation(650)
        self.jSplitPaneInfo.setOneTouchExpandable(True) 

        self.jPanel_reqInfo_left = JPanel()
        self.jPanel_respInfo_right = JPanel()

        self.jPanel_reqInfo_left.setLayout(BorderLayout())
        self.jPanel_respInfo_right.setLayout(BorderLayout())

        self.jPanel_reqInfo_left.add(self.iRequestTextEditor.getComponent(),
                        BorderLayout.CENTER)
        self.jPanel_respInfo_right.add(self.iResponseTextEditor.getComponent(),
                        BorderLayout.CENTER)

        self.jSplitPaneInfo.add(self.jPanel_reqInfo_left, JSplitPane.LEFT)
        self.jSplitPaneInfo.add(self.jPanel_respInfo_right, JSplitPane.RIGHT)

        self.jSplitPaneV.add(self.jPanel_top, JSplitPane.TOP)
        self.jSplitPaneV.add(self.jSplitPaneInfo, JSplitPane.BOTTOM)

        self._callbacks.customizeUiComponent(self.jSplitPaneV)
        self._callbacks.customizeUiComponent(self.jPanel_top)
        self._callbacks.customizeUiComponent(self.jTabbedPane)
        self._callbacks.customizeUiComponent(self.jTable)
        self._callbacks.customizeUiComponent(self.jScrollPane1)
        self._callbacks.customizeUiComponent(self.jSplitPaneInfo)
        self._callbacks.customizeUiComponent(self.jPanel_reqInfo_left)
        self._callbacks.customizeUiComponent(self.jPanel_respInfo_right)
        self._callbacks.addSuiteTab(self)


        self._callbacks.registerHttpListener(self)
        self._callbacks.registerContextMenuFactory(self)

        return

    def getTabCaption(self):
        return 'TPLogScan'

    def getUiComponent(self):
        return self.jSplitPaneV


    def getRowCount(self):
        try:
            return self._log.size()
        except:
            return 0

    def getColumnCount(self):
        return 6

    def getColumnName(self, columnIndex):
        if columnIndex == 0:
            return "#"
        if columnIndex == 1:
            return "Host"
        if columnIndex == 2:
            return "Method"
        if columnIndex == 3:
            return "URL"
        if columnIndex == 4:
            return "Status"
        if columnIndex == 5:
            return "Length"
        return ""

    def getValueAt(self, rowIndex, columnIndex):
        logEntry = self._log.get(rowIndex)
        url = logEntry._url.toString()
        url_parse = urlparse.urlparse(url)
        if url_parse.netloc.find(':') != -1:
            netloc = url_parse.netloc[:url_parse.netloc.find(':')]
        host = url_parse.scheme + '://' + netloc
        path = url_parse.path
        if columnIndex == 0:
            return rowIndex+1
        if columnIndex == 1:
            return host
        if columnIndex == 2:
            return logEntry._method
        if columnIndex == 3:
            return path
        if columnIndex == 4:
            return logEntry._status_code
        if columnIndex == 5:
            return logEntry._length
        return ""

    def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
        # tool_name = self._callbacks.getToolName(toolFlag)
        # if tool_name != 'Extender':
        if toolFlag != 1024:
            return
        if messageIsRequest:
            return
        request_info = self._helpers.analyzeRequest(messageInfo)
        response_info = self._helpers.analyzeResponse(messageInfo.getResponse())
        response_headers = response_info.getHeaders()
        response_length = 0
        for header in response_headers:
            header = header.encode('utf-8')
            if header.startswith("Content-Length"):
                response_length = int(header.replace('Content-Length: ', ''))

        length = response_length if response_length > 0 else 0

        self._lock.acquire()
        row = self._log.size()
        self._log.add(LogEntry(toolFlag, self._callbacks.saveBuffersToTempFiles(messageInfo), request_info.getUrl(),request_info.getMethod(),response_info.getStatusCode(),length))
        self.fireTableRowsInserted(row, row)
        self._lock.release()

    
    def getHttpService(self):
        return self._currentlyDisplayedItem.getHttpService()

    def getRequest(self):
        return self._currentlyDisplayedItem.getRequest()

    def getResponse(self):
        return self._currentlyDisplayedItem.getResponse()

    def loadMenus(self):
        self.menus = []
        self.mainMenu = JMenu("TPLogScan")
        self.menus.append(self.mainMenu)
        menu = JMenuItem('ThinkPHP v3', None, actionPerformed=lambda x: self.eventHandler(x))
        self.mainMenu.add(menu)
        menu = JMenuItem('ThinkPHP v5', None, actionPerformed=lambda x: self.eventHandler(x))
        self.mainMenu.add(menu)

    def createMenuItems(self, invocation):
        self.loadMenus()
        self.messages = invocation.getSelectedMessages()
        return self.menus if self.menus else None

    def eventHandler(self, x):
        menuName = x.getSource().text
        if menuName == 'ThinkPHP v3':
            version = 3
        elif menuName == 'ThinkPHP v5':
            version = 5
        else:
            print("chose error")
            return 

        for message in self.messages:
            url = str(self._helpers.analyzeRequest(message).getUrl())
            url_parse = urlparse.urlparse(url)
            url = url_parse.scheme + '://' + url_parse.netloc
            print("[*] url: {}".format(url))

            datetime_now = datetime.datetime.now()
            year = (datetime_now - datetime.timedelta(days=30)).year
            month = (datetime_now - datetime.timedelta(days=30)).month
            day = (datetime_now - datetime.timedelta(days=30)).day

            tplogscan  = TPLogScan(url, version, year, month, day)
            log_path = tplogscan.checkLogPath()
            if not log_path:
                print("[-] {} can't get log file! ".format(url))
                self._callbacks.issueAlert("{} can't get log file".format(url))
                return

            filename_list = tplogscan.genFileName()
            t = threading.Thread(target=self.logScan, args=(message, version, log_path, filename_list))
            t.start()

    def logScan(self, message, version, log_path, filename_list):
        http_service = message.getHttpService()
        old_request = self._helpers.bytesToString(message.getRequest())
        old_path = self._helpers.analyzeRequest(message).getUrl().getPath()
        for filename in filename_list:
            try:
                new_request = old_request.replace(" " + old_path + " HTTP/", " " + log_path+filename + " HTTP/")
                response, status_code = self.sendRequest(http_service, new_request)
                if status_code != 200:
                    continue
                tmp_filename = filename
                now_filename = ''
                pattern = re.compile(r"\[ (\d{4}-\d{2}-\d{2})T((\d{2}:){2}\d{2})\+08:00 \]")
                flag = True
                while flag:
                    match_result = pattern.search(response)
                    if not match_result:
                        break
                    time_str = match_result.group(1) + ' ' + match_result.group(2)
                    timeArray = time.strptime(time_str, "%Y-%m-%d %H:%M:%S")
                    timestamp = int(time.mktime(timeArray))
                    timestamp_list = [str(timestamp), str(timestamp-1), str(timestamp-2), str(timestamp-3)]
                    for timestamp in timestamp_list:
                        if version == 3:
                            tmp_filename = timestamp + '-' + filename
                        else:
                            tmp_filename = filename[:filename.find('/')] + '/' + timestamp + '-' + filename[filename.find('/')+1:]
                        if tmp_filename == now_filename:
                            flag = False
                            break
                        new_request = old_request.replace(" " + old_path + " HTTP/", " " + log_path+tmp_filename + " HTTP/")
                        response, status_code = self.sendRequest(http_service, new_request)
                        if status_code == 200:
                            now_filename = tmp_filename
                            break
            except Exception as e:
                print("[-] error: {}".format(e))
        print('[*] Log Scan complete!')

    def sendRequest(self, http_service, new_request):
        checkRequestResponse = self._callbacks.makeHttpRequest(http_service, self._helpers.stringToBytes(new_request))
        status_code = self._helpers.analyzeResponse(checkRequestResponse.getResponse()).getStatusCode()
        print('[*] {} | {}'.format(self._helpers.analyzeRequest(checkRequestResponse).getUrl(), status_code))
        return self._helpers.bytesToString(checkRequestResponse.getResponse()), status_code
コード例 #24
0
class BurpExtender(IBurpExtender, IContextMenuFactory, ITab, ComponentListener,
                   ActionListener, MouseAdapter):
    # contains the messages to show in the messages table
    _table_data = []

    # contains the messages to translate
    _messages = []

    # used to keep track when to refresh the table
    _reload_table = False

    _sql_file = None

    def registerExtenderCallbacks(self, callbacks):

        self._panel = JPanel()
        self._panel.setLayout(BorderLayout())
        #self._panel.setSize(400,400)

        # sourrounding try\except because Burp is not giving enough info
        try:

            # creating all the UI elements
            # create the split pane
            self._split_pane_horizontal = JSplitPane(
                JSplitPane.HORIZONTAL_SPLIT)
            self._split_panel_vertical = JSplitPane(JSplitPane.VERTICAL_SPLIT)

            # create panels
            self._panel_top = JPanel()
            self._panel_top.setLayout(BorderLayout())
            self._panel_bottom = JPanel()
            self._panel_bottom.setLayout(BorderLayout())
            self._panel_right = JPanel()
            self._panel_right.setLayout(BorderLayout())
            self._panel_request = JPanel()
            self._panel_request.setLayout(BorderLayout())
            self._panel_response = JPanel()
            self._panel_response.setLayout(BorderLayout())

            # create the tabbed pane used to show request\response
            self._tabbed_pane = JTabbedPane(JTabbedPane.TOP)

            # create the tabbed pane used to show aslan++\concretization file
            self._tabbed_pane_editor = JTabbedPane(JTabbedPane.TOP)

            # create the bottom command for selecting the SQL file and
            # generating the model
            self._button_generate = JButton(
                'Generate!', actionPerformed=self._generate_model)
            self._button_save = JButton('Save',
                                        actionPerformed=self._save_model)
            self._button_select_sql = JButton(
                'Select SQL', actionPerformed=self._select_sql_file)
            self._text_field_sql_file = JTextField(20)

            self._panel_bottom_commands = JPanel()
            layout = GroupLayout(self._panel_bottom_commands)
            layout.setAutoCreateGaps(True)
            layout.setAutoCreateContainerGaps(True)
            seq_layout = layout.createSequentialGroup()
            seq_layout.addComponent(self._text_field_sql_file)
            seq_layout.addComponent(self._button_select_sql)
            seq_layout.addComponent(self._button_generate)
            seq_layout.addComponent(self._button_save)
            layout.setHorizontalGroup(seq_layout)

            # create the message editors that will be used to show request and response
            self._message_editor_request = callbacks.createMessageEditor(
                None, True)
            self._message_editor_response = callbacks.createMessageEditor(
                None, True)

            # create the table that will be used to show the messages selected for
            # the translation

            self._columns_names = ('Host', 'Method', 'URL')
            dataModel = NonEditableModel(self._table_data, self._columns_names)
            self._table = JTable(dataModel)
            self._scrollPane = JScrollPane()
            self._scrollPane.getViewport().setView((self._table))

            popmenu = JPopupMenu()
            delete_item = JMenuItem("Delete")
            delete_item.addActionListener(self)
            popmenu.add(delete_item)
            self._table.setComponentPopupMenu(popmenu)
            self._table.addMouseListener(self)

            # add all the elements
            self._panel_request.add(
                self._message_editor_request.getComponent())
            self._panel_response.add(
                self._message_editor_response.getComponent())

            self._tabbed_pane.addTab("Request", self._panel_request)
            self._tabbed_pane.addTab("Response", self._panel_response)

            self._panel_top.add(self._scrollPane, BorderLayout.CENTER)

            self._panel_bottom.add(self._tabbed_pane, BorderLayout.CENTER)
            scroll = JScrollPane(self._panel_bottom)

            self._panel_right.add(self._tabbed_pane_editor,
                                  BorderLayout.CENTER)
            self._panel_right.add(self._panel_bottom_commands,
                                  BorderLayout.PAGE_END)

            self._split_panel_vertical.setTopComponent(self._panel_top)
            self._split_panel_vertical.setBottomComponent(scroll)
            self._split_pane_horizontal.setLeftComponent(
                self._split_panel_vertical)
            self._split_pane_horizontal.setRightComponent(self._panel_right)

            self._panel.addComponentListener(self)
            self._panel.add(self._split_pane_horizontal)

            self._callbacks = callbacks
            callbacks.setExtensionName("WAFEx")
            callbacks.addSuiteTab(self)
            callbacks.registerContextMenuFactory(self)
        except Exception as e:
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            print(exc_type, fname, exc_tb.tb_lineno)

    def getTabCaption(self):
        return "WAFEx"

    def getUiComponent(self):
        try:
            Platform.runLater(EditorTabUI(self))
            return self._panel
        except Exception as e:
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            print(exc_type, fname, exc_tb.tb_lineno)

    def componentShown(self, e):
        self._split_pane_horizontal.setDividerLocation(0.25)
        # populate the table with the selected requests\response
        try:
            if self._reload_table:
                print("reload")
                self._table_data = [
                ]  # empty _table_data (not too cool but quick)
                for c in self._messages:
                    msg = c[0]
                    http_request = converter._byte_array_to_string(
                        msg.getRequest())
                    request_parser = HttpParser()
                    request_parser.execute(http_request, len(http_request))

                    host = msg.getHttpService().getHost()
                    page = request_parser.get_url()
                    method = request_parser.get_method()

                    tmp = [host, method, page]
                    self._table_data += [tmp]
                self._table.getModel().setDataVector(self._table_data,
                                                     self._columns_names)
                self._reload_table = False
        except Exception as e:
            print(e)

    def componentHidden(self, e):
        return

    def componentMoved(self, e):
        return

    def componentResized(self, e):
        self._split_pane_horizontal.setDividerLocation(0.25)

    def createMenuItems(self, invocation):
        ret = []
        try:
            if (invocation.getInvocationContext() ==
                    invocation.CONTEXT_TARGET_SITE_MAP_TABLE):
                menu = JMenuItem("Send to WAFEx")
                messages = invocation.getSelectedMessages()

                def listener(e):
                    """ Generates a new WAFEx model. """
                    #self._generateWAFExModel(messages)
                    self._addToGeneration(messages)

                menu.addActionListener(listener)
                ret.append(menu)
        except Exception as e:
            print(e)
        return ret

    def mouseClicked(self, e):
        """ Positions the Aslan++ editor to the selected request position. """
        try:
            index = self._table.getSelectedRow()
            c = self._messages[index]
            print(len(c))
            message = c[0]
            tag = c[1]
            self._message_editor_request.setMessage(message.getRequest(), True)
            self._message_editor_response.setMessage(message.getResponse(),
                                                     False)
            if tag != None:
                document = self._jfxp_aslanpp._editor.getText()
                start, end = self._search_tag_position(tag, document)
                self._jfxp_aslanpp._editor.moveTo(start)
                self._jfxp_aslanpp._editor.selectRange(start, end)
                self._jfxp_aslanpp._editor.requestFollowCaret()
                self._jfxp_aslanpp._editor.requestFocus()
        except Exception as e:
            print(e)

    def actionPerformed(self, e):
        """ Performs the delete action. """
        try:
            index = self._table.getSelectedRow()
            del self._table_data[index]
            del self._messages[index]
            self._table.getModel().setDataVector(self._table_data,
                                                 self._columns_names)
        except Exception as e:
            print(e)

    def _search_tag_position(self, tag, text):
        """ Searches for a particular tag in a given text and return its position. """
        pattern = self._search_pattern.format(tag)
        for m in re.finditer(pattern, text):
            return m.start(), m.end()

    def _save_model(self, e):
        """ Saves the current Aslan++ model and concretization file. """
        try:
            chooseFile = JFileChooser()
            filter_ = FileNameExtensionFilter("txt files", ["txt"])
            chooseFile.addChoosableFileFilter(filter_)

            ret = chooseFile.showDialog(self._panel, "Choose file")

            if ret == JFileChooser.APPROVE_OPTION:
                self._model_name = chooseFile.getSelectedFile().getPath()
                with open("{}.aslan++".format(self._model_name), "w") as f:
                    skeleton = self._jfxp_aslanpp._editor.getText()
                    skeleton = skeleton.replace("@filename",
                                                basename(self._model_name))
                    f.write(skeleton)
                print("model created")

                with open("{}.txt".format(self._model_name), "w") as f:
                    f.write(self._jfxp_concretization._editor.getText())

        except Exception as e:
            print(e)

    def _select_sql_file(self, e):
        """ Shows a JFileChooser dialog to select the SQL file to use for creating
        the model. """
        try:
            chooseFile = JFileChooser()
            filter_ = FileNameExtensionFilter("txt files", ["txt"])
            chooseFile.addChoosableFileFilter(filter_)

            ret = chooseFile.showDialog(self._panel, "Choose file")

            if ret == JFileChooser.APPROVE_OPTION:
                self._sql_file = chooseFile.getSelectedFile().getPath()
            else:
                self._sql_file = None
            self._text_field_sql_file.setText("" + self._sql_file)
        except Exception as e:
            print(e)

    def _addToGeneration(self, messages):
        for msg in messages:
            self._messages += [[msg, None]]
        self._reload_table = True

    def _generate_model(self, e):
        if len(self._messages) <= 0:
            frame = JFrame("Error")
            JOptionPane.showMessageDialog(frame, "No messages!", "Error",
                                          JOptionPane.ERROR_MESSAGE)
            return
        if self._sql_file == None:
            frame = JFrame("Error")
            replay = JOptionPane.showConfirmDialog(
                frame, "No SQL file selected!\nDo you want to continue?",
                "Info", JOptionPane.YES_NO_OPTION)
            if replay == JOptionPane.NO_OPTION:
                return

        # create a new AslanppModel
        model = AslanppModel()
        # save _sql_file
        model._sql_file = self._sql_file

        for c in self._messages:
            # from byte to char Request and Response
            # for some reason b can be a negative value causing a crash
            # so I put a check to ensure b is in the right range
            msg = c[0]
            if msg.getRequest() == None or msg.getResponse() == None:
                # do not convert empty messages
                continue
            http_request = "".join(
                chr(b) for b in msg.getRequest() if b >= 0 and b <= 256)
            http_response = "".join(
                chr(b) for b in msg.getResponse() if b >= 0 and b <= 256)
            protocol = msg.getHttpService().getProtocol()
            # save the tag number generate by _parseHttpRequestResponse in the _messages array
            c[1] = converter._parseHttpRequestResponse(model, http_request,
                                                       http_response, protocol)

        # generate the ASLan++ code
        self._model, self._concrete = converter._generateWAFExModel(model)
        Platform.runLater(
            UpdateEditor(self._jfxp_aslanpp._editor,
                         self._jfxp_concretization._editor, self._model,
                         self._concrete))
コード例 #25
0
class BurpExtender(IBurpExtender, IContextMenuFactory, ActionListener, IMessageEditorController, ITab, ITextEditor, IHttpService, IScanIssue, IHttpRequestResponseWithMarkers):

    def __init__(self):
        self.menuItem = JMenuItem('Generate Finding')
        self.menuItem.addActionListener(self)   

    # implement IBurpExtender
    def registerExtenderCallbacks(self, callbacks):
    
        # keep a reference to our callbacks object (Burp Extensibility Feature)
        self._callbacks = callbacks   
        self._helpers = callbacks.getHelpers()

        # set our extension name
        callbacks.setExtensionName("Generate Finding")
        callbacks.registerContextMenuFactory(self)

        # -- Request Response Viewers -- #

        # create the lower half for the Request Response tabs...
        # Request and response from selection
        self._tabbedPane = JTabbedPane()
        tabs = self._tabbedPane
        self._requestViewer = callbacks.createMessageEditor(self, True)
        self._responseViewer = callbacks.createMessageEditor(self, True)
        self._requestHighlight = callbacks.createTextEditor()
        self._responseHighlight = callbacks.createTextEditor()
        tabs.addTab("Supporting Request", self._requestViewer.getComponent())
        tabs.addTab("Supporting Response", self._responseViewer.getComponent())
        tabs.addTab("Request Marker Selection", self._requestHighlight.getComponent())
        tabs.addTab("Response Marker Selection", self._responseHighlight.getComponent())
        #self._mainFrame.setRightComponent(tabs) # set to the lower split pane
        print "*" * 60
        print "[+] Request/Response tabs created"
    

        # -- Define Issue Details GUI & Layout-- #

        # Labels and Input boxes...
        # Issue Name
        self.issueNameLabel = JLabel(" Issue Name:")
        self.issueNameValue = JTextArea(text = str(issueNamePlaceholder), 
                         editable = True,
                         wrapStyleWord = True,
                         lineWrap = True,
                         alignmentX = Component.LEFT_ALIGNMENT,
                         size = (1, 20)
                         )

        # Issue Detail
        self.issueDetailLabel = JLabel(" Issue Detail:")

        #self.issueDetailValue = JTextField(str(issueDetailPlaceholder), 15)
        self.issueDetailValue = JTextArea(text = str(issueDetailPlaceholder), 
                         editable = True,
                         wrapStyleWord = True,
                         lineWrap = True,
                         alignmentX = Component.LEFT_ALIGNMENT,
                         size = (100, 20)
                         )

        # IssueBackground
        self.issueBackgroundLabel = JLabel(" Issue Background:")
        self.issueBackgroundValue = JTextArea(text = str(issueBackgroundPlaceholder), 
                         editable = True,
                         wrapStyleWord = True,
                         lineWrap = True,
                         alignmentX = Component.LEFT_ALIGNMENT,
                         size = (100, 20)
                         )

        # Remediation Detail
        self.issueRemediationLabel = JLabel(" Remediation Detail:")
        self.issueRemediationValue = JTextArea(text = str(remediationDetailPlaceholder), 
                         editable = True,
                         wrapStyleWord = True,
                         lineWrap = True,
                         alignmentX = Component.LEFT_ALIGNMENT,
                         size = (100, 20)
                         )
 
         # Remediation Background
        self.issueRemBackgroundLabel = JLabel(" Remediation Background:")
        self.issueRemBackgroundValue = JTextArea(text = str(remediationBackgroundPlaceholder), 
                         editable = True,
                         wrapStyleWord = True,
                         lineWrap = True,
                         alignmentX = Component.LEFT_ALIGNMENT,
                         size = (100, 20)
                         )  

        # Issue URL
        self.issueURLLabel = JLabel(" URL (path = http://domain/path):")
        self.issueURLValue = JTextArea(text = str(issueURLPlaceholder), 
                         editable = True,
                         wrapStyleWord = True,
                         lineWrap = True,
                         alignmentX = Component.LEFT_ALIGNMENT,
                         size = (1, 20)
                         )                       

        # Issue Port
        self.issuePortLabel = JLabel(" Port:")
        self.issuePortValue = JTextArea(text = str(issuePortPlaceholder), 
                         editable = True,
                         wrapStyleWord = True,
                         lineWrap = True,
                         alignmentX = Component.LEFT_ALIGNMENT,
                         size = (1, 20)
                         )

        # Confidence
        self.confidenceValuesList = ("Certain","Firm","Tentative")
        self.issueConfienceLabel = JLabel(" Confidence [Certain, Firm or Tentative]")
        self.issueConfidenceValue = JComboBox(self.confidenceValuesList)

        # Severity
        self.severityValuesList = ("High","Medium","Low","Information")
        self.issueSeverityLabel = JLabel(" Severity [High, Medium Low or Informational]")
        self.issueSeverityValue = JComboBox(self.severityValuesList)

        # Add Finding button

        self.addFindingButton = JButton("Generate Finding", actionPerformed=self.createScanIssue, alignmentX=Component.CENTER_ALIGNMENT) 


        # -- Group items for display -- #         

        # Group items 
        self.grpIssueSummary = JPanel(GridLayout(0,1))
        self.grpIssueSummary.add(self.issueNameLabel)
        self.grpIssueSummary.add(self.issueNameValue)
        self.grpIssueSummary.add(self.issueDetailLabel)
        self.grpIssueSummary.add(self.issueDetailValue)
        self.grpIssueSummary.add(self.issueBackgroundLabel)
        self.grpIssueSummary.add(self.issueBackgroundValue)
        self.grpIssueSummary.add(self.issueRemediationLabel)
        self.grpIssueSummary.add(self.issueRemediationValue)
        self.grpIssueSummary.add(self.issueRemBackgroundLabel)
        self.grpIssueSummary.add(self.issueRemBackgroundValue)
        self.grpIssueSummary.add(self.issueURLLabel)
        self.grpIssueSummary.add(self.issueURLValue)
        self.grpIssueSummary.add(self.issuePortLabel)
        self.grpIssueSummary.add(self.issuePortValue)
        self.grpIssueSummary.add(self.issueURLLabel)
        self.grpIssueSummary.add(self.issueURLValue)
        self.grpIssueSummary.add(self.issuePortLabel)
        self.grpIssueSummary.add(self.issuePortValue)

        self.grpRatingBoxes = JPanel()
        self.grpRatingBoxes.add(self.issueSeverityLabel)
        self.grpRatingBoxes.add(self.issueSeverityValue)
        self.grpRatingBoxes.add(self.issueConfienceLabel)
        self.grpRatingBoxes.add(self.issueConfidenceValue)
        self.grpRatingBoxes.add(self.addFindingButton)


        # add grps to details frame
        self._detailsPanel = JPanel(GridLayout(0,1))
        self._detailsPanel.add(self.grpIssueSummary)
        self._detailsPanel.add(self.grpRatingBoxes)


        self._findingDetailsPane = JScrollPane(self._detailsPanel)
        # create the main frame to hold details
        self._detailsViewer = self._findingDetailsPane # creates a form for details
        #tabs.addTab("Finding Details", self._detailsViewer)

        self._mainFrame = JSplitPane(JSplitPane.VERTICAL_SPLIT, self._detailsViewer, tabs)
        self._mainFrame.setOneTouchExpandable(True);
        self._mainFrame.setDividerLocation(0.5)
        self._mainFrame.setResizeWeight(0.50)

        print "[+] Finding details panel created"
        print "[+] Rendering..."

        # customize our UI components
        callbacks.customizeUiComponent(self._mainFrame)
        callbacks.customizeUiComponent(self._tabbedPane)
        callbacks.customizeUiComponent(self._detailsPanel)
        callbacks.customizeUiComponent(tabs)
        
        # add the custom tab to Burp's UI
        callbacks.addSuiteTab(self)
        print "[+] Done"
        print "[!] Added suite tab initialize complete!"

        return



    def getTabCaption(self):
        return "Generate Finding" 



    def getUiComponent(self):
        return self._mainFrame



    # initiaizes when button is clicked in 'Generate Finding Tab'
    def createScanIssue(self, event):

        print "[!] Finding Detail: "

        print "\t[+] Name:\n\t\t", self.issueNameValue.getText().strip()
        name = self.issueNameValue.getText()
        print "\t[+] Description:\n\t\t", self.issueDetailValue.getText().strip()
        description = self.issueDetailValue.getText()
        print "\t[+] Background:\n\t\t", self.issueBackgroundValue.getText().strip()
        background = self.issueBackgroundValue.getText()
        print "\t[+] Remediation:\n\t\t", self.issueRemediationValue.getText().strip()
        remediation = self.issueRemediationValue.getText()
        print "\t[+] Remediation Background:\n\t\t", self.issueRemBackgroundValue.getText().strip()
        remBackground = self.issueRemBackgroundValue.getText()
        print "\t[+] URL Detail:\n\t\t", self.issueURLValue.getText()
        urlDetail = self.issueURLValue.getText()
        print "\t[+] Port Number:\n\t\t", self.issuePortValue.getText()
        portNumber = self.issuePortValue.getText()
        print "\t[+] Confidence Rating:\n\t\t", self.issueConfidenceValue.getSelectedItem()
        confidenceRating = self.issueConfidenceValue.getSelectedItem()
        print "\t[+] Severity Rating:\n\t\t", self.issueSeverityValue.getSelectedItem()
        severityRating = self.issueSeverityValue.getSelectedItem()
        #print "\t[+] Payload Markers:\n\t\t", self.getSelectionBounds()

        # get highlighted data from request/response tabs in 'Generate Finding'
        #print "[!] Request Selected data:", self._requestViewer.getSelectedData()
        #highRequest = self._requestViewer.getSelectedData()
        #print "converted:", self._helpers.bytesToString(highRequest) 
        #print "[!] Response Selected data:", self._responseViewer.getSelectedData()
        #highResponse = self._responseViewer.getSelectedData()
        #print "converted:", self._helpers.bytesToString(highResponse) 

        # current message is used - should work as long as menu item 'Generate Finding' is not reset or used before finding has been generated.
        requestResponse = self.current_message

        print "\t[+] RequestResponse:\n\t\t", requestResponse
        print "\t[+] Service:\n\t\t", requestResponse.getHttpService()        


        # Collect request and Response Markers...
        #print "[**] Request Bounds: ", self._requestHighlight.getSelectionBounds() 
        requestBounds = self._requestHighlight.getSelectionBounds()
        #print "[**] Response Bounds: ", self._responseHighlight.getSelectionBounds() 
        responseBounds = self._responseHighlight.getSelectionBounds()

        # applyMarkers to request/response
        # callbacks.applyMarkers(requestResponse, None, [array('i', (data[1], data[2]))])
        self.reqMarkers = [requestBounds[0],requestBounds[1]]
        print "\t[+] Request Reporting Markers:\n\t\t", self.reqMarkers
        self.resMarkers = [responseBounds[0],responseBounds[1]]
        print "\t[+] Response Reporting Markers:\n\t\t", self.resMarkers

        print "*" * 60
        print "[!] Attempting to create custom scan issue."
        # Call AddScanItem class to create scan issue!!
        finding_array = [urlDetail, name, 134217728, severityRating, confidenceRating, background, remBackground, description, remediation, requestResponse]

        issue = ScanIssue(self, finding_array, self.current_message, self.reqMarkers, self.resMarkers, self._helpers, self._callbacks)
        self._callbacks.addScanIssue(issue)

        # Done
        print "[+] Finding Generated!"


    def getRequestResponseText(self):

        messages = self.ctxMenuInvocation.getSelectedMessages()

        # parses currently selected finding to a string
        if len(messages) == 1 :

            for self.m in messages:

                requestResponse = self.m
                # add requestResponseWithMarkers to be global so can be included in scanIssue
                self.current_message = requestResponse

                # get request data and convert to string
                requestDetail = requestResponse.getRequest()  
                try: 
                    requestData = self._helpers.bytesToString(requestDetail) # converts & Prints out the entire request as string     
                except:
                    requestData = '[-] No Request Detail in this RequestResponse'
                    pass
                # get response data and convert to string
                responseDetail = requestResponse.getResponse()
                try:
                    responseData = self._helpers.bytesToString(responseDetail) # converts & Prints out the entire request as string 
                except:
                    responseData = '[-] No Response Detail in this RequestResponse' 
                    pass 
                requestData = self._helpers.bytesToString(requestDetail) # converts & Prints out the entire request as string     


            # send request string to 'Supporting Request' tab - 'True' because it is a request!
            self._requestViewer.setMessage(requestData, True)
            # for higlighting markers..
            self._requestHighlight.setText(requestData)

            # send response string to 'Supporting Response' tab
            self._responseViewer.setMessage(responseData, False) # set False as is a response not request... 
            # for higlighting markers..
            self._responseHighlight.setText(responseData)
           


    def getFindingDetails(self):

            messages = self.ctxMenuInvocation.getSelectedMessages()

            print "*" * 60
            print "[+] Handling selected request: ", self.current_message

            if len(messages) == 1:
                for m in messages:           

                    # URL
                    #print "[!] Selected Request's URL: \n", self._helpers.analyzeRequest(m).getUrl()
                    self.issueURLValue.setText(str(self._helpers.analyzeRequest(m).getUrl())) # update finding info

                    # Protocol
                    #print "[!] Request's Protocol: \n", m.getProtocol()

                    # Request Port
                    #print "[!] Request's Port: \n", m.getPort()
                    self.issuePortValue.setText(str(m.getPort())) # update finding info
                    print "*" * 60


# API hook...

    def getHttpMessages(self):

        return [self.m]


# Actions on menu click...

    def actionPerformed(self, actionEvent):
        print "*" * 60
        print "[+] Request sent to 'Generate Finding'"
        try:
            # When clicked!! 
            self.getRequestResponseText()
            self.getFindingDetails()
        except:
            tb = traceback.format_exc()
            print tb


# create Menu

    def createMenuItems(self, ctxMenuInvocation):
        self.ctxMenuInvocation = ctxMenuInvocation
        return [self.menuItem]