Esempio n. 1
0
class SimpleEditor(java.lang.Runnable):

    #---------------------------------------------------------------------------
    # Name: run()
    # Role: Build and display our graphical application
    # Note: Invoked by the Swing Event Dispatch Thread
    #---------------------------------------------------------------------------
    def run(self):
        frame = JFrame('Simple Editor',
                       layout=BorderLayout(),
                       defaultCloseOperation=JFrame.EXIT_ON_CLOSE)

        #-----------------------------------------------------------------------
        # The JTextArea will be used to hold the user entered text.
        #-----------------------------------------------------------------------
        self.area = JTextArea(rows=8, columns=32, caretUpdate=self.caretUpdate)
        frame.add(JScrollPane(self.area), BorderLayout.CENTER)
        self.words = JLabel('# words: 0  # lines: 0')
        frame.add(self.words, BorderLayout.SOUTH)

        frame.pack()
        frame.setVisible(1)

    #---------------------------------------------------------------------------
    # Name: caretUpdate()
    # Role: Build and display our graphical application
    # Note: This is a brute force implementation, just to demonstrate some ideas
    #---------------------------------------------------------------------------
    def caretUpdate(self, event, regexp=None):
        if not regexp:
            regexp = re.compile('\W+', re.MULTILINE)
        pos = event.getDot()
        text = self.area.getText()
        if text.strip() == '':
            words = lines = 0
        else:
            words = len(re.split(regexp, text))
            lines = len(text.splitlines())
        msg = '# words: %d  # lines: %d' % (words, lines)
        self.words.setText(msg)
Esempio n. 2
0
class Process_EVTX1WithUISettingsPanel(IngestModuleIngestJobSettingsPanel):
    # Note, we can't use a self.settings instance variable.
    # Rather, self.local_settings is used.
    # https://wiki.python.org/jython/UserGuide#javabean-properties
    # Jython Introspector generates a property - 'settings' on the basis
    # of getSettings() defined in this class. Since only getter function
    # is present, it creates a read-only 'settings' property. This auto-
    # generated read-only property overshadows the instance-variable -
    # 'settings'

    # We get passed in a previous version of the settings so that we can
    # prepopulate the UI
    # TODO: Update this for your UI
    def __init__(self, settings):
        self.local_settings = settings
        self.initComponents()
        self.customizeComponents()

    # TODO: Update this for your UI
    def checkBoxEvent(self, event):
        if self.checkbox.isSelected():
            self.local_settings.setSetting('All', 'true')
        else:
            self.local_settings.setSetting('All', 'false')
        if self.checkbox1.isSelected():
            self.local_settings.setSetting('Application', 'true')
        else:
            self.local_settings.setSetting('Application', 'false')
        if self.checkbox2.isSelected():
            self.local_settings.setSetting('Security', 'true')
        else:
            self.local_settings.setSetting('Security', 'false')
        if self.checkbox3.isSelected():
            self.local_settings.setSetting('System', 'true')
        else:
            self.local_settings.setSetting('System', 'false')
        if self.checkbox4.isSelected():
            self.local_settings.setSetting('Other', 'true')
            self.area.setEnabled(True)
        else:
            self.local_settings.setSetting('Other', 'false')
            self.area.setEnabled(False)
        if self.filterCheckbox.isSelected():
            self.local_settings.setSetting('Filter', 'true')
            self.filterField.setEnabled(True)
            self.filterSelector.setEnabled(True)
            self.filterInput.setEnabled(True)
        else:
            self.local_settings.setSetting('Filter', 'false')
            self.filterField.setEnabled(False)
            self.filterSelector.setEnabled(False)
            self.filterInput.setEnabled(False)
        if self.sortCheckbox.isSelected():
            self.local_settings.setSetting('SortDesc', 'true')
        else:
            self.local_settings.setSetting('SortDesc', 'false')

    def keyPressed(self, event):
        self.local_settings.setSetting('EventLogs', self.area.getText())

    # TODO: Update this for your UI
    def initComponents(self):
        self.setLayout(BoxLayout(self, BoxLayout.Y_AXIS))
        self.setAlignmentX(JComponent.LEFT_ALIGNMENT)

        self.checkbox = JCheckBox("All Logs",
                                  actionPerformed=self.checkBoxEvent)
        self.checkbox1 = JCheckBox("Application.Evtx",
                                   actionPerformed=self.checkBoxEvent)
        self.checkbox2 = JCheckBox("Security.EVTX",
                                   actionPerformed=self.checkBoxEvent)
        self.checkbox3 = JCheckBox("System.EVTX",
                                   actionPerformed=self.checkBoxEvent)
        self.checkbox4 = JCheckBox(
            "Other - Input in text area below then check this box",
            actionPerformed=self.checkBoxEvent)

        # Scrollable text area for additional log names
        self.area = JTextArea(3, 10)
        self.area.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0))
        self.area.setEnabled(False)
        self.pane = JScrollPane()
        self.pane.getViewport().add(self.area)

        self.add(self.checkbox)
        self.add(self.checkbox1)
        self.add(self.checkbox2)
        self.add(self.checkbox3)
        self.add(self.checkbox4)
        self.add(self.pane)

        self.add(JSeparator())
        self.add(JSeparator())

        self.filterCheckbox = JCheckBox("Filter",
                                        actionPerformed=self.checkBoxEvent)
        self.filterCheckbox.setLayout(
            BoxLayout(self.filterCheckbox, BoxLayout.X_AXIS))
        self.add(self.filterCheckbox)

        self.filterPanel = JPanel()
        self.filterPanel.setLayout(
            BoxLayout(self.filterPanel, BoxLayout.X_AXIS))
        self.filterField = JComboBox([
            "Computer Name", "Event Identifier", "Event Level", "Source Name",
            "Event Detail"
        ])
        self.filterField.setEnabled(False)
        self.filterField.setMaximumSize(self.filterField.getPreferredSize())
        self.filterSelector = JComboBox(
            ["equals", "not equals", "contains", "starts with", "ends with"])
        self.filterSelector.setEnabled(False)
        self.filterSelector.setMaximumSize(
            self.filterSelector.getPreferredSize())
        self.filterInput = JTextField()
        self.filterInput.setEnabled(False)
        self.filterInput.setMaximumSize(
            Dimension(512,
                      self.filterInput.getPreferredSize().height))
        self.filterPanel.add(self.filterField)
        self.filterPanel.add(self.filterSelector)
        self.filterPanel.add(self.filterInput)

        self.add(self.filterPanel)

        self.sortCheckbox = JCheckBox("Sort Event Counts Descending",
                                      actionPerformed=self.checkBoxEvent)
        self.add(self.sortCheckbox)

    # TODO: Update this for your UI
    def customizeComponents(self):
        self.checkbox.setSelected(
            self.local_settings.getSetting('All') == 'true')
        self.checkbox1.setSelected(
            self.local_settings.getSetting('Application') == 'true')
        self.checkbox2.setSelected(
            self.local_settings.getSetting('Security') == 'true')
        self.checkbox3.setSelected(
            self.local_settings.getSetting('System') == 'true')
        self.checkbox4.setSelected(
            self.local_settings.getSetting('Other') == 'true')
        self.area.setText(self.local_settings.getSetting('EventLogs'))

    # Return the settings used
    def getSettings(self):
        self.local_settings.setSetting('EventLogs', self.area.getText())
        self.local_settings.setSetting('FilterField',
                                       self.filterField.getSelectedItem())
        self.local_settings.setSetting('FilterMode',
                                       self.filterSelector.getSelectedItem())
        self.local_settings.setSetting('FilterInput',
                                       self.filterInput.getText())
        return self.local_settings
Esempio n. 3
0
class BurpExtender(IBurpExtender, IBurpExtenderCallbacks, IIntruderPayloadProcessor, ITab, IExtensionStateListener):
    def registerExtenderCallbacks( self, callbacks):
        self._helpers = callbacks.getHelpers()
        callbacks.setExtensionName("JWT FuzzHelper")
        callbacks.registerIntruderPayloadProcessor(self)
        callbacks.registerExtensionStateListener(self)
        
        self._stdout = PrintWriter(callbacks.getStdout(), True)
        self._stderr = PrintWriter(callbacks.getStderr(), True)

        # Holds values passed by user from Configuration panel
        self._fuzzoptions = { 
                                "target" : "Header", 
                                "selector" : None, 
                                "signature" : False,
                                "algorithm" : "HS256",
                                "key" : "",
                                "key_cmd" : ""
                            }

        self._isNone = lambda val: isinstance(val, type(None))

        # Configuration panel Layout
        self._configurationPanel = JPanel()
        gridBagLayout = GridBagLayout()
        gridBagLayout.columnWidths = [ 0, 0, 0]
        gridBagLayout.rowHeights = [ 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
        gridBagLayout.columnWeights = [ 0.0, 0.0, 0.0 ]
        gridBagLayout.rowWeights = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
        self._configurationPanel.setLayout(gridBagLayout)

        # Setup tabs
        self._tabs = JTabbedPane()
        self._tabs.addTab('Configuration',self._configurationPanel)
        #self._tabs.addTab('Help',self._helpPanel)

        # Target Options
        targetLabel = JLabel("Target Selection (Required): ")
        targetLabel.setFont(Font("Tahoma",Font.BOLD, 12))
        c = GridBagConstraints()
        c.gridx = 0
        c.gridy = 1
        c.insets = Insets(0,10,0,0)
        c.anchor = GridBagConstraints.LINE_END
        self._configurationPanel.add(targetLabel,c)

        options = [ 'Header', 'Payload' ]
        self._targetComboBox = JComboBox(options)
        c = GridBagConstraints()
        c.gridx = 1
        c.gridy = 1
        c.anchor = GridBagConstraints.LINE_START
        self._configurationPanel.add(self._targetComboBox,c)

        # Help Button
        self._helpButton = JButton("Help", actionPerformed=self.helpMenu)
        c = GridBagConstraints()
        c.gridx = 2
        c.gridy = 1
        c.anchor = GridBagConstraints.FIRST_LINE_START
        self._configurationPanel.add(self._helpButton,c)

        # Selector Options
        self._selectorLabel = JLabel("JSON Selector [Object Identifier-Index Syntax] (Required): ")
        self._selectorLabel.setFont(Font("Tahoma",Font.BOLD, 12))
        c = GridBagConstraints()
        c.gridx = 0
        c.gridy = 2
        c.insets = Insets(0,10,0,0)
        c.anchor = GridBagConstraints.LINE_END
        self._configurationPanel.add(self._selectorLabel, c)

        self._selectorTextField = JTextField('',50)
        c = GridBagConstraints()
        c.gridx = 1
        c.gridy = 2
        self._configurationPanel.add(self._selectorTextField, c)

        # Regex option

        self._regexLabel = JLabel("Use regex as JSON Selector? (Optional): ")
        self._regexLabel.setFont(Font("Tahoma",Font.BOLD, 12))
        c = GridBagConstraints()
        c.gridx = 0
        c.gridy = 3
        c.insets = Insets(0,0,0,0)
        c.anchor = GridBagConstraints.LINE_END
        self._configurationPanel.add(self._regexLabel,c)

        self._regexCheckBox = JCheckBox("", actionPerformed=self.regexSelector)
        c = GridBagConstraints()
        c.gridx = 1
        c.gridy = 3
        c.anchor = GridBagConstraints.FIRST_LINE_START
        self._configurationPanel.add(self._regexCheckBox,c)

        # Signature Options
        generateSignatureLabel = JLabel("Generate signature? (Required): ")
        generateSignatureLabel.setFont(Font("Tahoma",Font.BOLD, 12))
        c = GridBagConstraints()
        c.gridx = 0
        c.gridy = 4
        c.insets = Insets(0,10,0,0)
        c.anchor = GridBagConstraints.LINE_END
        self._configurationPanel.add(generateSignatureLabel,c)

        options = ["False", "True"]
        self._generateSignatureComboBox = JComboBox(options)
        c = GridBagConstraints()
        c.gridx = 1
        c.gridy = 4
        c.anchor = GridBagConstraints.LINE_START
        self._configurationPanel.add(self._generateSignatureComboBox,c)

        signatureAlgorithmLabel = JLabel("Signature Algorithm (Optional): ")
        signatureAlgorithmLabel.setFont(Font("Tahoma",Font.BOLD, 12))
        c = GridBagConstraints()
        c.gridx = 0
        c.gridy = 5
        c.insets = Insets(0,10,0,0)
        c.anchor = GridBagConstraints.LINE_END
        self._configurationPanel.add(signatureAlgorithmLabel,c)

        options = ["None", "HS256","HS384","HS512","ES256","ES384","ES512","RS256","RS384","RS512","PS256","PS256","PS384","PS512"]
        self._algorithmSelectionComboBox = JComboBox(options)
        c = GridBagConstraints()
        c.gridx = 1
        c.gridy = 5
        c.anchor = GridBagConstraints.LINE_START
        self._configurationPanel.add(self._algorithmSelectionComboBox,c)

        # Signing key options
        self._signingKeyLabel = JLabel("Signing Key (Optional): ")
        self._signingKeyLabel.setFont(Font("Tahoma",Font.BOLD, 12))
        c = GridBagConstraints()
        c.gridx = 0
        c.gridy = 6
        c.insets = Insets(0,10,0,0)
        c.anchor = GridBagConstraints.LINE_END
        self._configurationPanel.add(self._signingKeyLabel,c)

        self.addSigningKeyTextArea()
        self._fromFileTextField = JTextField('',50) 

        fromFileLabel = JLabel("Signing key from file? (Optional): ")
        fromFileLabel.setFont(Font("Tahoma",Font.BOLD, 12))
        c = GridBagConstraints()
        c.gridx = 0
        c.gridy = 7
        c.insets = Insets(0,0,0,0)
        c.anchor = GridBagConstraints.LINE_END
        self._configurationPanel.add(fromFileLabel,c)

        self._fromFileCheckBox = JCheckBox("", actionPerformed=self.fromFile)
        c = GridBagConstraints()
        c.gridx = 1
        c.gridy = 7
        c.anchor = GridBagConstraints.FIRST_LINE_START
        self._configurationPanel.add(self._fromFileCheckBox,c)

        self._fromCmdTextField = JTextField('',50)

        fromCmdLabel = JLabel("Signing key from command? (Optional): ")
        fromCmdLabel.setFont(Font("Tahoma",Font.BOLD, 12))
        c = GridBagConstraints()
        c.gridx = 0
        c.gridy = 8
        c.insets = Insets(0,0,0,0)
        c.anchor = GridBagConstraints.LINE_END
        self._configurationPanel.add(fromCmdLabel,c)

        self._fromCmdCheckBox = JCheckBox("", actionPerformed=self.fromCmd)
        c = GridBagConstraints()
        c.gridx = 1
        c.gridy = 8
        c.anchor = GridBagConstraints.FIRST_LINE_START
        self._configurationPanel.add(self._fromCmdCheckBox,c)

        self._saveButton = JButton("Save Configuration", actionPerformed=self.saveOptions)
        self._saveButton.setText("Save Configuration")
        c = GridBagConstraints()
        c.gridx = 1
        c.gridy = 9
        c.anchor = GridBagConstraints.FIRST_LINE_START
        self._configurationPanel.add(self._saveButton,c)

        
        callbacks.customizeUiComponent(self._configurationPanel)
        callbacks.customizeUiComponent(self._tabs)
        callbacks.addSuiteTab(self)

        self._stdout.println("[JWT FuzzHelper] Loaded successfully")
        return


    def getProcessorName(self):
        return "JWT Fuzzer"

    def extensionUnloaded(self):
        del self._configurationPanel
        return

    # Intruder logic function
    def processPayload(self, currentPayload, originalPayload, baseValue):
        dataParameter = self._helpers.bytesToString(
                         self._helpers.urlDecode(baseValue)
                       )

        # utf-8 encode
        header,payload,signature = [unicode(s).encode('utf-8') for s in dataParameter.split(".",3)]
        decoded_header = self._helpers.bytesToString(
                            self._helpers.base64Decode(header + "=" * (-len(header) % 4))
                        )
        decoded_payload = self._helpers.bytesToString(
                            self._helpers.base64Decode(payload+"=" * (-len(payload) % 4))
                        )

        # Decode header and payload, preserving order if they are JSON objects

        # Decode header
        try:
            header_dict = json.loads(decoded_header, object_pairs_hook=OrderedDict)
        except ValueError:
            raise RuntimeException("[JWT FuzzHelper] Error: ValueError. Failed to decode header!")
        except Exception as e:
            self._stderr.println("[ERROR] Encountered an unknown error when decoding header:\n{}\nCarrying on...".format(e))

        # Decode payload
        # Payload does not have to be a JSON object.
        #   Ref: https://github.com/auth0/node-jsonwebtoken#usage
        payload_is_string = False
        try:
            payload_dict = json.loads(decoded_payload, object_pairs_hook=OrderedDict)
        except ValueError:
            payload_is_string = True
            payload_dict = decoded_payload
        except Exception as e:
            self._stderr.println("[ERROR] Encountered an unknown error when decoding payload:\n{}\nCarrying on...".format(e))

        target = header_dict if self._fuzzoptions["target"] == "Header" else payload_dict
        selector = self._fuzzoptions["selector"]

        # If using Object Identifier-Index then retrieve the 
        # value specified by the selector, 
        # if this value does not exist, assume the user
        # wants to add the value that would have been specified
        # by the selector to the desired JWT segment (this behavior will 
        # be noted in the help docs)

        intruderPayload = self._helpers.bytesToString(currentPayload)
        if not self._fuzzoptions["regex"]:
            if selector != [""]:
                try:
                    value = self.getValue(target, selector)
                except Exception:
                    target = self.buildDict(target, selector)

            if not self._isNone(selector) and selector != [""]:
                target = self.setValue(target, selector, intruderPayload)
        
        # Simple match-replace for regex
        if self._fuzzoptions["regex"]:
            target_string = target if payload_is_string else json.dumps(target)
            target_string = re.sub(selector, intruderPayload, target_string)
            target = target_string if payload_is_string else json.loads(target_string, object_pairs_hook=OrderedDict)
            if self._fuzzoptions["target"] == "Payload":
                payload_dict = target
            else:
                header_dict = target
                

        algorithm = self._fuzzoptions["algorithm"]
        if self._fuzzoptions["signature"]: 
            # pyjwt requires lowercase 'none'. If user wants to try
            # "none", "NonE", "nOnE", etc... they should use .alg
            # as selector, delete sig from intruder and use those
            # permutations as their fuzz list (outlined in help docs)
            # and keep "Generate Signature" as False
            algorithm = "none" if algorithm.lower() == "none" else algorithm
            header_dict["alg"] = algorithm

        header = json.dumps(header_dict, separators=(",",":"))
        payload = payload_dict if payload_is_string else json.dumps(payload_dict, separators=(",",":"))
        header = self._helpers.base64Encode(header).strip("=")
        payload = self._helpers.base64Encode(payload).strip("=")

        contents = header + "." + payload
        
        key = self._fuzzoptions["key"]

        if len(self._fuzzoptions["key_cmd"]) > 0:
            # we provide 'contents' value as an only argument to key-generating command
            # it is expected that the command will print only the signature
            signature = check_output([self._fuzzoptions["key_cmd"], contents])
            modified_jwt = contents + "." + signature
        elif self._fuzzoptions["signature"]:
            # pyjwt throws error when using a public key in symmetric alg (for good reason of course),
            # must do natively to support algorithmic sub attacks
            if algorithm.startswith("HS"):
                if algorithm == "HS256":
                    hmac_algorithm = hashlib.sha256
                elif algorithm == "HS384":
                    hmac_algorithm = hashlib.sha384
                else:
                    hmac_algorithm = hashlib.sha512
            
                signature = self._helpers.base64Encode(
                            hmac.new(
                                    key, contents, hmac_algorithm
                                ).digest()
                    ).strip("=")

                modified_jwt = contents + "." +signature

            # JWT can't sign non-JSON payloads. WTF. This block is for non-JSON payloads.
            elif algorithm.startswith("RS") and payload_is_string:
                if algorithm == "RS256":
                    rsa_algorithm = "SHA-256"
                elif algorithm == "RS384":
                    rsa_algorithm = "SHA-384"
                else:
                    rsa_algorithm = "SHA-512"
                privkey = rsa.PrivateKey.load_pkcs1(key)
                signature = rsa.sign(contents,privkey,rsa_algorithm)
                signature = base64.b64encode(signature).encode('utf-8').replace("=", "")
                modified_jwt = contents + "." + signature
            else:
                # Use pyjwt when using asymmetric alg
                if algorithm == "none":
                    key = ""
                modified_jwt = jwt.encode(payload_dict,key,algorithm=algorithm,headers=header_dict)
        else:
            modified_jwt = contents + "." + signature

        return self._helpers.stringToBytes(modified_jwt)

    
    #-----------------------
    # getValue:
    #   @return: A value at arbitrary depth in dictionary
    #   @throws: TypeError
    #-----------------------
    def getValue(self, dictionary, values):
        return reduce(dict.__getitem__, values, dictionary)

    #-----------------------
    # buildDict:
    #   @note: Will build dictionary of arbitrary depth
    #-----------------------
    def buildDict(self, dictionary, keys):
        if self._isNone(keys):
            return dictionary

        root = current = dictionary
        for key in keys:
            if key not in current:
                current[key] = {}
            current = current[key]
        return root

    #----------------------
    # setValue:
    #   @note: Will set key of arbitrary depth
    #-----------------------
    def setValue(self, dictionary, keys, value):
        root = current = dictionary
        for i,key in enumerate(keys):
            if i == len(keys) - 1:
                current[key] = value
                break
            if key in current:
                current = current[key]
            else:
                # Should never happen
                current = self.buildDict(current, keys)
        return root
    
    #-----------------------
    # addSigningKeyTextArea:
    #   @note: Will toggle if fromFile selected. Be DRY.
    #----------------------
    def addSigningKeyTextArea(self):
        self._signingKeyTextArea = JTextArea()
        self._signingKeyTextArea.setColumns(50)
        self._signingKeyTextArea.setRows(10)
        self._signingKeyScrollPane = JScrollPane(self._signingKeyTextArea)
        c = GridBagConstraints()
        c.gridx = 1
        c.gridy = 6
        c.anchor = GridBagConstraints.LINE_START
        self._configurationPanel.add(self._signingKeyScrollPane,c)

    def addSigningKeyFromFileTextField(self):
        c = GridBagConstraints()
        c.gridx = 1
        c.gridy = 6
        self._configurationPanel.add(self._fromFileTextField, c)

    def addSigningKeyFromCmdTextField(self):
        c = GridBagConstraints()
        c.gridx = 1
        c.gridy = 6
        self._configurationPanel.add(self._fromCmdTextField, c)
    #-----------------------
    # End Helpers
    #-----------------------

    #-----------------------
    # Implement ITab
    #-----------------------

    def getTabCaption(self):
        return "JWT FuzzHelper"

    def getUiComponent(self):
        return self._tabs

    #---------------------------
    # Save configuration options
    #---------------------------

    def saveOptions(self,event):
        self._fuzzoptions["target"]     = self._targetComboBox.getSelectedItem()
        self._fuzzoptions["selector"]   = self._selectorTextField.getText()
        self._fuzzoptions["signature"]  = True if self._generateSignatureComboBox.getSelectedItem() == "True" else False
        self._fuzzoptions["algorithm"]  = self._algorithmSelectionComboBox.getSelectedItem()
        self._fuzzoptions["key_cmd"]    = ""
        
        if self._fromFileCheckBox.isSelected():
            filename = self._fromFileTextField.getText()
            if os.path.isdir(filename):
                self._stderr.println("{} is a directory".format(filename))
                return
            if os.path.exists(filename):
                with open(filename, 'rb') as f:
                    self._fuzzoptions["key"] = f.read()
        elif self._fromCmdCheckBox.isSelected():
            self._fuzzoptions["key_cmd"] = self._fromCmdTextField.getText()
        else:
            self._fuzzoptions["key"]    = unicode(self._signingKeyTextArea.getText()).encode("utf-8")
        # RSA keys need to end with a line break. Many headaches because of this.
        if not self._fuzzoptions["key"].endswith("\n") and self._fuzzoptions["algorithm"].startswith("RS"):
            self._fuzzoptions["key"] += "\n"
        self._stdout.println("[JWT FuzzHelper] Saved options:\n{}".format(self._fuzzoptions))


        # Sanity check selector if it's not a regular expression
        self._fuzzoptions["regex"] = self._regexCheckBox.isSelected()
        if not self._regexCheckBox.isSelected():
            m = re.search("(\.\w+)+",self._fuzzoptions["selector"])
            if self._fuzzoptions["selector"] != "." and (isinstance(m,type(None)) or m.group(0) != self._fuzzoptions["selector"]):
                self._saveButton.setText("Invalid JSON Selector!")
            else:
                self._fuzzoptions["selector"] = self._fuzzoptions["selector"].split(".")[1:]
                self._saveButton.setText("Saved!")
        # Sanity check the regular expression
        else:
            try:
                re.compile(self._fuzzoptions["selector"])
                self._saveButton.setText("Saved!")
            except re.error:
                self._saveButton.setText("Invalid Regex!")
        return

    #-------------------------
    # From file options
    #------------------------
    def fromFile(self,event):
        if self._fromFileCheckBox.isSelected():
            self._signingKeyLabel.setText("Path to Signing Key (Optional): ")
            self._configurationPanel.remove(self._signingKeyScrollPane)
            self.addSigningKeyFromFileTextField()
        else:
            self._signingKeyLabel.setText("Signing Key (Optional): ")
            self._configurationPanel.remove(self._fromFileTextField)
            self.addSigningKeyTextArea()
        self._configurationPanel.repaint()
        return

    def fromCmd(self,event):
        if self._fromCmdCheckBox.isSelected():
            self._signingKeyLabel.setText("Path to Signing Cmd (Optional): ")
            self._configurationPanel.remove(self._signingKeyScrollPane)
            self.addSigningKeyFromCmdTextField()
        else:
            self._signingKeyLabel.setText("Signing Key (Optional): ")
            self._configurationPanel.remove(self._fromCmdTextField)
            self.addSigningKeyTextArea()
        self._configurationPanel.repaint()
        return

    def regexSelector(self,event):
        if self._regexCheckBox.isSelected():
            self._selectorLabel.setText("Selector [Regex] (Required): ")
        else:
            self._selectorLabel.setText("JSON Selector [Object Identifier-Index Syntax] (Required): ")
        self._configurationPanel.repaint()
        return
    #-------------------------
    # Help popup
    #-------------------------
    def helpMenu(self,event):
        self._helpPopup = JFrame('JWT Fuzzer', size=(550, 450) );
        self._helpPopup.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)
        helpPanel = JPanel()
        helpPanel.setPreferredSize(Dimension(550, 450))
        helpPanel.setBorder(EmptyBorder(10, 10, 10, 10))
        helpPanel.setLayout(BoxLayout(helpPanel, BoxLayout.Y_AXIS))
        self._helpPopup.setContentPane(helpPanel)
        helpHeadingText = JLabel("<html><h2>JWT Fuzzer</h2></html>")
        authorText = JLabel("<html><p>@author: &lt;pinnace&gt;</p></html>")
        aboutText = JLabel("<html><br /> <p>This extension adds an Intruder payload processor for JWTs.</p><br /></html>")
        repositoryText = JLabel("<html>Documentation and source code:</html>")
        repositoryLink = JLabel("<html>- <a href=\"https://github.com/pinnace/burp-jwt-fuzzhelper-extension\">https://github.com/pinnace/burp-jwt-fuzzhelper-extension</a></html>")
        licenseText = JLabel("<html><br/><p>JWT Fuzzer uses a GPL 3 license. This license does not apply to the dependency below:<p></html>") 
        dependencyLink = JLabel("<html>- <a href=\"https://github.com/jpadilla/pyjwt/blob/master/LICENSE\">pyjwt</a></html>")
        dependencyLink.addMouseListener(ClickListener())
        dependencyLink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR))
        repositoryLink.addMouseListener(ClickListener())
        repositoryLink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR))
        
        helpPanel.add(helpHeadingText)
        helpPanel.add(authorText)
        helpPanel.add(aboutText)
        helpPanel.add(repositoryText)
        helpPanel.add(repositoryLink)
        helpPanel.add(licenseText)
        helpPanel.add(dependencyLink)

        self._helpPopup.setSize(Dimension(550, 450))
        self._helpPopup.pack()
        self._helpPopup.setLocationRelativeTo(None)
        self._helpPopup.setVisible(True)
        return
Esempio n. 4
0
class BurpExtender(IBurpExtender, ITab, IHttpListener,
                   IMessageEditorController, AbstractTableModel,
                   IContextMenuFactory):
    def registerExtenderCallbacks(self, callbacks):
        # keep a reference to our callbacks object
        self._callbacks = callbacks
        # obtain an extension helpers object
        self._helpers = callbacks.getHelpers()

        # set our extension name
        callbacks.setExtensionName("Autorize")

        # create the log and a lock on which to synchronize when adding log entries
        self._log = ArrayList()
        self._lock = Lock()
        self.intercept = 0

        self.initInterceptionFilters()

        self.initEnforcementDetector()

        self.initExport()

        self.initConfigurationTab()

        self.initTabs()

        self.initCallbacks()

        print "Thank you for installing Autorize v0.9 extension"
        print "by Barak Tawily"
        return

    def initExport(self):
        #
        ## init enforcement detector tab
        #

        exportLType = JLabel("File Type:")
        exportLType.setBounds(10, 10, 100, 30)

        exportLES = JLabel("Enforcement Statuses:")
        exportLES.setBounds(10, 50, 160, 30)

        exportFileTypes = ["HTML"]
        self.exportType = JComboBox(exportFileTypes)
        self.exportType.setBounds(100, 10, 200, 30)

        exportES = [
            "All Statuses", "Authorization bypass!",
            "Authorization enforced??? (please configure enforcement detector)",
            "Authorization enforced!"
        ]
        self.exportES = JComboBox(exportES)
        self.exportES.setBounds(100, 50, 200, 30)

        exportLES = JLabel("Statuses:")
        exportLES.setBounds(10, 50, 100, 30)

        self.exportButton = JButton("Export",
                                    actionPerformed=self.exportToHTML)
        self.exportButton.setBounds(390, 25, 100, 30)

        self.exportPnl = JPanel()
        self.exportPnl.setLayout(None)
        self.exportPnl.setBounds(0, 0, 1000, 1000)
        self.exportPnl.add(exportLType)
        self.exportPnl.add(self.exportType)
        self.exportPnl.add(exportLES)
        self.exportPnl.add(self.exportES)
        self.exportPnl.add(self.exportButton)

    def initEnforcementDetector(self):
        #
        ## init enforcement detector tab
        #

        self.EDFP = ArrayList()
        self.EDCT = ArrayList()

        EDLType = JLabel("Type:")
        EDLType.setBounds(10, 10, 140, 30)

        EDLContent = JLabel("Content:")
        EDLContent.setBounds(10, 50, 140, 30)

        EDLabelList = JLabel("Filter List:")
        EDLabelList.setBounds(10, 165, 140, 30)

        EDStrings = [
            "Finger Print: (enforced message body contains)",
            "Content-Length: (constant Content-Length number of enforced response)"
        ]
        self.EDType = JComboBox(EDStrings)
        self.EDType.setBounds(80, 10, 430, 30)

        self.EDText = JTextArea("", 5, 30)
        self.EDText.setBounds(80, 50, 300, 110)

        self.EDModel = DefaultListModel()
        self.EDList = JList(self.EDModel)
        self.EDList.setBounds(80, 175, 300, 110)
        self.EDList.setBorder(LineBorder(Color.BLACK))

        self.EDAdd = JButton("Add filter", actionPerformed=self.addEDFilter)
        self.EDAdd.setBounds(390, 85, 120, 30)
        self.EDDel = JButton("Remove filter", actionPerformed=self.delEDFilter)
        self.EDDel.setBounds(390, 210, 120, 30)

        self.EDPnl = JPanel()
        self.EDPnl.setLayout(None)
        self.EDPnl.setBounds(0, 0, 1000, 1000)
        self.EDPnl.add(EDLType)
        self.EDPnl.add(self.EDType)
        self.EDPnl.add(EDLContent)
        self.EDPnl.add(self.EDText)
        self.EDPnl.add(self.EDAdd)
        self.EDPnl.add(self.EDDel)
        self.EDPnl.add(EDLabelList)
        self.EDPnl.add(self.EDList)

    def initInterceptionFilters(self):
        #
        ##  init interception filters tab
        #

        IFStrings = [
            "URL Contains: ", "Scope items only: (Content is not required)"
        ]
        self.IFType = JComboBox(IFStrings)
        self.IFType.setBounds(80, 10, 430, 30)

        self.IFModel = DefaultListModel()
        self.IFList = JList(self.IFModel)
        self.IFList.setBounds(80, 175, 300, 110)
        self.IFList.setBorder(LineBorder(Color.BLACK))

        self.IFText = JTextArea("", 5, 30)
        self.IFText.setBounds(80, 50, 300, 110)

        IFLType = JLabel("Type:")
        IFLType.setBounds(10, 10, 140, 30)

        IFLContent = JLabel("Content:")
        IFLContent.setBounds(10, 50, 140, 30)

        IFLabelList = JLabel("Filter List:")
        IFLabelList.setBounds(10, 165, 140, 30)

        self.IFAdd = JButton("Add filter", actionPerformed=self.addIFFilter)
        self.IFAdd.setBounds(390, 85, 120, 30)
        self.IFDel = JButton("Remove filter", actionPerformed=self.delIFFilter)
        self.IFDel.setBounds(390, 210, 120, 30)

        self.filtersPnl = JPanel()
        self.filtersPnl.setLayout(None)
        self.filtersPnl.setBounds(0, 0, 1000, 1000)
        self.filtersPnl.add(IFLType)
        self.filtersPnl.add(self.IFType)
        self.filtersPnl.add(IFLContent)
        self.filtersPnl.add(self.IFText)
        self.filtersPnl.add(self.IFAdd)
        self.filtersPnl.add(self.IFDel)
        self.filtersPnl.add(IFLabelList)
        self.filtersPnl.add(self.IFList)

    def initConfigurationTab(self):
        #
        ##  init configuration tab
        #
        self.prevent304 = JCheckBox("Prevent 304 Not Modified status code")
        self.prevent304.setBounds(290, 25, 300, 30)

        self.ignore304 = JCheckBox("Ignore 304/204 status code responses")
        self.ignore304.setBounds(290, 5, 300, 30)
        self.ignore304.setSelected(True)

        self.autoScroll = JCheckBox("Auto Scroll")
        self.autoScroll.setBounds(290, 45, 140, 30)

        startLabel = JLabel("Authorization checks:")
        startLabel.setBounds(10, 10, 140, 30)
        self.startButton = JButton("Autorize is off",
                                   actionPerformed=self.startOrStop)
        self.startButton.setBounds(160, 10, 120, 30)
        self.startButton.setBackground(Color(255, 100, 91, 255))

        self.clearButton = JButton("Clear List",
                                   actionPerformed=self.clearList)
        self.clearButton.setBounds(10, 40, 100, 30)

        self.replaceString = JTextArea("Cookie: Insert=injected; header=here;",
                                       5, 30)
        self.replaceString.setWrapStyleWord(True)
        self.replaceString.setLineWrap(True)
        self.replaceString.setBounds(10, 80, 470, 180)

        self.filtersTabs = JTabbedPane()
        self.filtersTabs.addTab("Enforcement Detector", self.EDPnl)
        self.filtersTabs.addTab("Interception Filters", self.filtersPnl)
        self.filtersTabs.addTab("Export", self.exportPnl)

        self.filtersTabs.setBounds(0, 280, 2000, 700)

        self.pnl = JPanel()
        self.pnl.setBounds(0, 0, 1000, 1000)
        self.pnl.setLayout(None)
        self.pnl.add(self.startButton)
        self.pnl.add(self.clearButton)
        self.pnl.add(self.replaceString)
        self.pnl.add(startLabel)
        self.pnl.add(self.autoScroll)
        self.pnl.add(self.ignore304)
        self.pnl.add(self.prevent304)
        self.pnl.add(self.filtersTabs)

    def initTabs(self):
        #
        ##  init autorize tabs
        #

        self.logTable = Table(self)
        self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT)
        self._splitpane.setResizeWeight(1)
        self.scrollPane = JScrollPane(self.logTable)
        self._splitpane.setLeftComponent(self.scrollPane)
        self.scrollPane.getVerticalScrollBar().addAdjustmentListener(
            autoScrollListener(self))
        copyURLitem = JMenuItem("Copy URL")
        copyURLitem.addActionListener(copySelectedURL(self))
        self.menu = JPopupMenu("Popup")
        self.menu.add(copyURLitem)

        self.tabs = JTabbedPane()
        self._requestViewer = self._callbacks.createMessageEditor(self, False)
        self._responseViewer = self._callbacks.createMessageEditor(self, False)

        self._originalrequestViewer = self._callbacks.createMessageEditor(
            self, False)
        self._originalresponseViewer = self._callbacks.createMessageEditor(
            self, False)

        self.tabs.addTab("Modified Request",
                         self._requestViewer.getComponent())
        self.tabs.addTab("Modified Response",
                         self._responseViewer.getComponent())

        self.tabs.addTab("Original Request",
                         self._originalrequestViewer.getComponent())
        self.tabs.addTab("Original Response",
                         self._originalresponseViewer.getComponent())

        self.tabs.addTab("Configuration", self.pnl)
        self.tabs.setSelectedIndex(4)
        self._splitpane.setRightComponent(self.tabs)

    def initCallbacks(self):
        #
        ##  init callbacks
        #

        # customize our UI components
        self._callbacks.customizeUiComponent(self._splitpane)
        self._callbacks.customizeUiComponent(self.logTable)
        self._callbacks.customizeUiComponent(self.scrollPane)
        self._callbacks.customizeUiComponent(self.tabs)
        self._callbacks.customizeUiComponent(self.filtersTabs)
        self._callbacks.registerContextMenuFactory(self)
        # add the custom tab to Burp's UI
        self._callbacks.addSuiteTab(self)

    #
    ## Events functions
    #
    def startOrStop(self, event):
        if self.startButton.getText() == "Autorize is off":
            self.startButton.setText("Autorize is on")
            self.startButton.setBackground(Color.GREEN)
            self.intercept = 1
            self._callbacks.registerHttpListener(self)
        else:
            self.startButton.setText("Autorize is off")
            self.startButton.setBackground(Color(255, 100, 91, 255))
            self.intercept = 0
            self._callbacks.removeHttpListener(self)

    def addEDFilter(self, event):
        typeName = self.EDType.getSelectedItem().split(":")[0]
        self.EDModel.addElement(typeName + ": " + self.EDText.getText())

    def delEDFilter(self, event):
        index = self.EDList.getSelectedIndex()
        if not index == -1:
            self.EDModel.remove(index)

    def addIFFilter(self, event):
        typeName = self.IFType.getSelectedItem().split(":")[0]
        self.IFModel.addElement(typeName + ": " + self.IFText.getText())

    def delIFFilter(self, event):
        index = self.IFList.getSelectedIndex()
        if not index == -1:
            self.IFModel.remove(index)

    def clearList(self, event):
        self._lock.acquire()
        self._log = ArrayList()
        row = self._log.size()
        self.fireTableRowsInserted(row, row)
        self._lock.release()

    def exportToHTML(self, event):
        parentFrame = JFrame()
        fileChooser = JFileChooser()
        fileChooser.setSelectedFile(File("AutorizeReprort.html"))
        fileChooser.setDialogTitle("Save Autorize Report")
        userSelection = fileChooser.showSaveDialog(parentFrame)
        if userSelection == JFileChooser.APPROVE_OPTION:
            fileToSave = fileChooser.getSelectedFile()

        enforcementStatusFilter = self.exportES.getSelectedItem()
        htmlContent = """<html><title>Autorize Report by Barak Tawily</title>
        <style>
        .datagrid table { border-collapse: collapse; text-align: left; width: 100%; }
         .datagrid {font: normal 12px/150% Arial, Helvetica, sans-serif; background: #fff; overflow: hidden; border: 1px solid #006699; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; }
         .datagrid table td, .datagrid table th { padding: 3px 10px; }
         .datagrid table thead th {background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; color:#FFFFFF; font-size: 15px; font-weight: bold; border-left: 1px solid #0070A8; } .datagrid table thead th:first-child { border: none; }.datagrid table tbody td { color: #00496B; border-left: 1px solid #E1EEF4;font-size: 12px;font-weight: normal; }.datagrid table tbody .alt td { background: #E1EEF4; color: #00496B; }.datagrid table tbody td:first-child { border-left: none; }.datagrid table tbody tr:last-child td { border-bottom: none; }.datagrid table tfoot td div { border-top: 1px solid #006699;background: #E1EEF4;} .datagrid table tfoot td { padding: 0; font-size: 12px } .datagrid table tfoot td div{ padding: 2px; }.datagrid table tfoot td ul { margin: 0; padding:0; list-style: none; text-align: right; }.datagrid table tfoot  li { display: inline; }.datagrid table tfoot li a { text-decoration: none; display: inline-block;  padding: 2px 8px; margin: 1px;color: #FFFFFF;border: 1px solid #006699;-webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; }.datagrid table tfoot ul.active, .datagrid table tfoot ul a:hover { text-decoration: none;border-color: #006699; color: #FFFFFF; background: none; background-color:#00557F;}div.dhtmlx_window_active, div.dhx_modal_cover_dv { position: fixed !important; }
        table {
        width: 100%;
        table-layout: fixed;
        }
        td {
            border: 1px solid #35f;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        td.a {
            width: 13%;
            white-space: nowrap;
        }
        td.b {
            width: 9%;
            word-wrap: break-word;
        }
        </style>
        <body>
        <h1>Autorize Report<h1>
        <div class="datagrid"><table>
        <thead><tr><th>URL</th><th>Authorization Enforcement Status</th></tr></thead>
        <tbody>"""

        for i in range(0, self._log.size()):
            color = ""
            if self._log.get(
                    i
            )._enfocementStatus == "Authorization enforced??? (please configure enforcement detector)":
                color = "yellow"
            if self._log.get(i)._enfocementStatus == "Authorization bypass!":
                color = "red"
            if self._log.get(i)._enfocementStatus == "Authorization enforced!":
                color = "LawnGreen"

            if enforcementStatusFilter == "All Statuses":
                htmlContent += "<tr bgcolor=\"%s\"><td><a href=\"%s\">%s</a></td><td>%s</td></tr>" % (
                    color, self._log.get(i)._url, self._log.get(i)._url,
                    self._log.get(i)._enfocementStatus)
            else:
                if enforcementStatusFilter == self._log.get(
                        i)._enfocementStatus:
                    htmlContent += "<tr bgcolor=\"%s\"><td><a href=\"%s\">%s</a></td><td>%s</td></tr>" % (
                        color, self._log.get(i)._url, self._log.get(i)._url,
                        self._log.get(i)._enfocementStatus)

        htmlContent += "</tbody></table></div></body></html>"
        f = open(fileToSave.getAbsolutePath(), 'w')
        f.writelines(htmlContent)
        f.close()

    #
    # implement IContextMenuFactory
    #
    def createMenuItems(self, invocation):
        responses = invocation.getSelectedMessages()
        if responses > 0:
            ret = LinkedList()
            requestMenuItem = JMenuItem("Send request to Autorize")
            cookieMenuItem = JMenuItem("Send cookie to Autorize")
            requestMenuItem.addActionListener(
                handleMenuItems(self, responses[0], "request"))
            cookieMenuItem.addActionListener(
                handleMenuItems(self, responses[0], "cookie"))
            ret.add(requestMenuItem)
            ret.add(cookieMenuItem)
            return (ret)
        return null

    #
    # implement ITab
    #
    def getTabCaption(self):
        return "Autorize"

    def getUiComponent(self):
        return self._splitpane

        #

    # extend AbstractTableModel
    #

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

    def getColumnCount(self):
        return 2

    def getColumnName(self, columnIndex):
        if columnIndex == 0:
            return "URL"
        if columnIndex == 1:
            return "Authorization Enforcement Status"
        return ""

    def getValueAt(self, rowIndex, columnIndex):
        logEntry = self._log.get(rowIndex)
        if columnIndex == 0:
            return logEntry._url.toString()
        if columnIndex == 1:
            return logEntry._enfocementStatus
        return ""

    #
    # implement IMessageEditorController
    # this allows our request/response viewers to obtain details about the messages being displayed
    #

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

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

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

    #
    # implement IHttpListener
    #
    def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
        if self.intercept == 1:
            if self.prevent304.isSelected():
                if messageIsRequest:
                    requestHeaders = list(
                        self._helpers.analyzeRequest(messageInfo).getHeaders())
                    newHeaders = list()
                    found = 0
                    for header in requestHeaders:
                        if not "If-None-Match:" in header and not "If-Modified-Since:" in header:
                            newHeaders.append(header)
                            found = 1
                    if found == 1:
                        requestInfo = self._helpers.analyzeRequest(messageInfo)
                        bodyBytes = messageInfo.getRequest()[requestInfo.
                                                             getBodyOffset():]
                        bodyStr = self._helpers.bytesToString(bodyBytes)
                        messageInfo.setRequest(
                            self._helpers.buildHttpMessage(
                                newHeaders, bodyStr))

            if not messageIsRequest:
                if not self.replaceString.getText(
                ) in self._helpers.analyzeRequest(messageInfo).getHeaders():
                    if self.ignore304.isSelected():
                        firstHeader = self._helpers.analyzeResponse(
                            messageInfo.getResponse()).getHeaders()[0]
                        if "304" in firstHeader or "204" in firstHeader:
                            return
                    if self.IFList.getModel().getSize() == 0:
                        self.checkAuthorization(
                            messageInfo,
                            self._helpers.analyzeResponse(
                                messageInfo.getResponse()).getHeaders())
                    else:
                        urlString = str(
                            self._helpers.analyzeRequest(messageInfo).getUrl())
                        for i in range(0, self.IFList.getModel().getSize()):
                            if self.IFList.getModel().getElementAt(i).split(
                                    ":")[0] == "Scope items only":
                                currentURL = URL(urlString)
                                if self._callbacks.isInScope(currentURL):
                                    self.checkAuthorization(
                                        messageInfo,
                                        self._helpers.analyzeResponse(
                                            messageInfo.getResponse()).
                                        getHeaders())
                            if self.IFList.getModel().getElementAt(i).split(
                                    ":")[0] == "URL Contains":
                                if self.IFList.getModel().getElementAt(
                                        i)[14:] in urlString:
                                    self.checkAuthorization(
                                        messageInfo,
                                        self._helpers.analyzeResponse(
                                            messageInfo.getResponse()).
                                        getHeaders())
        return

    def makeRequest(self, messageInfo, message):
        requestURL = self._helpers.analyzeRequest(messageInfo).getUrl()
        return self._callbacks.makeHttpRequest(
            self._helpers.buildHttpService(
                str(requestURL.getHost()), int(requestURL.getPort()),
                requestURL.getProtocol() == "https"), message)

    def makeMessage(self, messageInfo, removeOrNot):
        requestInfo = self._helpers.analyzeRequest(messageInfo)
        headers = requestInfo.getHeaders()
        if removeOrNot:
            headers = list(headers)
            removeHeaders = ArrayList()
            removeHeaders.add(self.replaceString.getText()
                              [0:self.replaceString.getText().index(":")])

            for header in headers[:]:
                for removeHeader in removeHeaders:
                    if removeHeader in header:
                        headers.remove(header)

            headers.append(self.replaceString.getText())

        msgBody = messageInfo.getRequest()[requestInfo.getBodyOffset():]
        return self._helpers.buildHttpMessage(headers, msgBody)

    def checkAuthorization(self, messageInfo, originalHeaders):
        message = self.makeMessage(messageInfo, True)
        requestResponse = self.makeRequest(messageInfo, message)
        analyzedResponse = self._helpers.analyzeResponse(
            requestResponse.getResponse())

        oldStatusCode = originalHeaders[0]
        newStatusCode = analyzedResponse.getHeaders()[0]
        oldContentLen = self.getContentLength(originalHeaders)
        newContentLen = self.getContentLength(analyzedResponse.getHeaders())

        impression = ""

        EDFilters = self.EDModel.toArray()
        if oldStatusCode == newStatusCode:
            if oldContentLen == newContentLen:
                impression = "Authorization bypass!"
            else:
                impression = "Authorization enforced??? (please configure enforcement detector)"
                for filter in EDFilters:
                    if str(filter).startswith("Content-Length: "):
                        if newContentLen == filter:
                            impression = "Authorization enforced!"
                    if str(filter).startswith("Finger Print: "):
                        if filter[14:] in self._helpers.bytesToString(
                                requestResponse.getResponse()
                            [analyzedResponse.getBodyOffset():]):
                            impression = "Authorization enforced!"
        else:
            impression = "Authorization enforced!"

        self._lock.acquire()
        row = self._log.size()
        self._log.add(
            LogEntry(self._callbacks.saveBuffersToTempFiles(requestResponse),
                     self._helpers.analyzeRequest(requestResponse).getUrl(),
                     messageInfo,
                     impression))  # same requests not include again.
        self.fireTableRowsInserted(row, row)
        self._lock.release()

    def getContentLength(self, analyzedResponseHeaders):
        for header in analyzedResponseHeaders:
            if "Content-Length:" in header:
                return header
        return "null"

    def getCookieFromMessage(self, messageInfo):
        headers = list(
            self._helpers.analyzeRequest(
                messageInfo.getRequest()).getHeaders())
        for header in headers:
            if "Cookie:" in header:
                return header
        return None
class BurpExtender(IBurpExtender, ITab):

    def registerExtenderCallbacks(self, callbacks):

        self._cb = callbacks
        self._hp = callbacks.getHelpers()

        self._cb.setExtensionName('MiniProgram Decrypto')
        print 'successful!'

        self.mainPanel = JPanel()

        

        self.sessionKey = JLabel("sessionKey:")
        self.sessionKey.setHorizontalAlignment(SwingConstants.LEFT);
        
        self.iv = JLabel("iv:")
        self.tfsessionKey = JTextField(50)
        
        self.tfiv = JTextField(50)
        
        self.textAreaPlaintext = JTextArea(30, 40)
        self.textAreaPlaintext.setLineWrap(True)
        self.textAreaPlaintext2 = JTextArea(30, 40)
        self.textAreaPlaintext2.setLineWrap(True)
        self.DecryptoBtn = JButton('Decrypto >', actionPerformed=self.decrypto_onClick)
        self.CryptoBtn = JButton('< Crypto', actionPerformed=self.encrypto_onClick)
        
        self.mainPanel.add(self.sessionKey)
        self.mainPanel.add(self.tfsessionKey)
        self.mainPanel.add(self.iv)
        self.mainPanel.add(self.tfiv)
        
        self.mainPanel.add(self.textAreaPlaintext)
        self.mainPanel.add(self.CryptoBtn)
        self.mainPanel.add(self.DecryptoBtn)
        

        self.mainPanel.add(self.textAreaPlaintext2)

        self._cb.customizeUiComponent(self.mainPanel)
        self._cb.addSuiteTab(self)

    def decrypto_onClick(self, event):
        self.textAreaPlaintext2.setText("")
        session_key = self.tfsessionKey.getText()
        iv = self.tfiv.getText()
        payload = self.textAreaPlaintext.getText().rstrip()
        
        str = self.decrypto(payload, session_key, iv)
        
        self.textAreaPlaintext2.append(str)

    def encrypto_onClick(self, event):
        self.textAreaPlaintext.setText("")
        session_key = self.tfsessionKey.getText()
        iv = self.tfiv.getText()
        payload = self.textAreaPlaintext2.getText().rstrip()
        
        str = self.encrypto(payload, session_key, iv)
        
        self.textAreaPlaintext.append(String(str))


    def getTabCaption(self):
    	return 'MiniProgram Decrypto'

    def getUiComponent(self):
        return self.mainPanel


    def encrypto(self, payload, key, iv):
		aesKey = SecretKeySpec(base64.b64decode(key), "AES")
		aesIV = IvParameterSpec(base64.b64decode(iv))
		cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
		cipher.init(Cipher.ENCRYPT_MODE, aesKey, aesIV)
		encrypted = cipher.doFinal(payload)
		return Base64.getEncoder().encode(encrypted)


    def decrypto(self, payload, key, iv):
		decoded = base64.b64decode(payload)
		
		aesKey = SecretKeySpec(base64.b64decode(key), "AES")
		
		aesIV = IvParameterSpec(base64.b64decode(iv))
		
		cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC")
		cipher.init(Cipher.DECRYPT_MODE, aesKey, aesIV)
		return String(cipher.doFinal(decoded)) 
Esempio n. 6
0
class BurpExtender(IBurpExtender, ITab):

    def registerExtenderCallbacks(self, callbacks):
        print 'JSON&HTTPP by [Vulkey_Chen]\nBlog: gh0st.cn\nTeam: MSTSEC'
        self._cb = callbacks
        self._hp = callbacks.getHelpers()
        self._cb.setExtensionName('JSON&HTTPP')
        self.mainPanel = JPanel()
        self.mainPanel.setLayout(BorderLayout())

        self.jsonTextArea = JTextArea(20,0)
        self.jsonTextArea.setLineWrap(True)

        self.dictTextArea = JTextArea()
        self.dictTextArea.setLineWrap(True)

        self.jsonTextWrapper = JPanel()
        self.jsonTextWrapper.setLayout(BorderLayout())
        self.dictTextWrapper = JPanel()
        self.dictTextWrapper.setLayout(BorderLayout())

        self.jsonScrollPane = JScrollPane(self.jsonTextArea)
        self.dictScrollPane = JScrollPane(self.dictTextArea)

        self.jsonTextWrapper.add(self.jsonScrollPane, BorderLayout.CENTER)
        self.dictTextWrapper.add(self.dictScrollPane, BorderLayout.CENTER)

        self.mainPanel.add(self.jsonTextWrapper, BorderLayout.NORTH)
        self.mainPanel.add(self.dictTextWrapper, BorderLayout.CENTER)

        self.beautifyButton_1 = JButton("JSON2HTTPP", actionPerformed=self.onClick1)
        self.beautifyButton_2 = JButton("HTTPP2JSON", actionPerformed=self.onClick2)

        self.buttons = JPanel();
        self.buttons.add(self.beautifyButton_1, BorderLayout.CENTER)
        self.buttons.add(self.beautifyButton_2, BorderLayout.CENTER)

        self.mainPanel.add(self.buttons, BorderLayout.SOUTH)

        self._cb.customizeUiComponent(self.mainPanel)
        self._cb.addSuiteTab(self)

    def onClick1(self, event):
        _jsontext = self.jsonTextArea.getText()
        try:
            _jsontext = json.loads(re.search(r'\({.*?}\)',_jsontext).group().replace('(','').replace(')',''))
        except:
            _jsontext = json.loads(_jsontext)
        self._result = []
        self.dictTextArea.setText('&'.join(self.json2dict(_jsontext)))
        # self.dictTextArea.setText('\n'.join(self.json2dict(_jsontext)))

    def onClick2(self, event):
        _jsontext = self.jsonTextArea.getText()
        _res = []
        for i in _jsontext.split('&'):
            for x in i.split('='):
                _res.append(x)
        self.dictTextArea.setText(json.dumps(dict(zip(_res[0::2],_res[1::2]))))

    def json2dict(self,_jsontext):
        keyValue = ""
        if isinstance(_jsontext, dict):
            for key in _jsontext.keys():
                keyValue = _jsontext.get(key)
                if isinstance(keyValue, dict):
                    self.json2dict(keyValue)
                elif isinstance(keyValue, list):
                    for json_array in keyValue:
                        self.json2dict(json_array)
                else:
                    if type(keyValue) is int or type(keyValue) == long or type(keyValue) == str:
                        self._result.append(str(key) + "=" + str(keyValue))
                    elif type(keyValue) is bool:
                        self._result.append(str(key) + "=" + str(int(keyValue)))
                    elif type(keyValue) == type(None):
                        self._result.append(str(key) + "=" + "")
                    else:
                        self._result.append(str(key) + "=" + keyValue)
        elif isinstance(_jsontext, list):
            for _jsontext_array in _jsontext:
                self.json2dict(_jsontext_array)
        return self._result

    def getTabCaption(self):
        return 'JSON&HTTPP'

    def getUiComponent(self):
        return self.mainPanel
class gui(JFrame):
    def __init__(self):

        #Class variable declarations
        self.mainPanel = JPanel(GridLayout(1,2))
        self.subPanel1 = JPanel(BorderLayout())
        self.subPanel2 = JPanel(GridLayout(5,1))
        
        self.userText = JTextArea(' ')
        
        self.emoticonFeedback = JTextArea('This will consider your emoticon usage.')
        self.curseFeedback = JTextArea('This will consider your use of profanity.')
        self.styleFeedback = JTextArea('This will consider your general tone.')
        self.overallFeedback = JTextArea('This will be your overall score.')
        
        self.button = JButton("Score my email!",
        						actionPerformed=self.updateScores)
        
        self.initGUI()
        self.add(self.mainPanel)
        
        self.setSize(800, 500)
        self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
        self.setVisible(True)

    def initGUI(self):
        #Set up subpanel1
        appName = JTextArea('Politeness Gauge\n'+'\nSarah Robinson \nAnna Clegg')
        appName.setLineWrap(True)
        appName.setWrapStyleWord(True)
        appName.setEditable(False)
        appName.background =  240,240,240
        instructions = JTextArea('   Ever agonized over whether or not your emails' +
                    ' are polite enough? \n    Never fear! With our politeness gauge' +
                    ' we can provide suggestions on improving your emails' +
                    ' with just the click of a button.  \n    Just type your email ' +
                    'into the text box below and hit Score!')
        instructions.setLineWrap(True)
        instructions.setWrapStyleWord(True)
        instructions.background = 240,240,240
        northPanel = JPanel(GridLayout(2,1))
        northPanel.add(appName)
        northPanel.add(instructions)
        self.subPanel1.add(northPanel, BorderLayout.NORTH)  
        
        self.userText.setEditable(True)
        self.userText.setLineWrap(True)
        self.userText.setWrapStyleWord(True)
        self.userText.setRows(100)
        #self.userText.wordWrap = True
        self.subPanel1.add(self.userText, BorderLayout.CENTER)
        
        self.subPanel1.add(self.button, BorderLayout.SOUTH)
        
        label = JLabel("Politeness Evaluation")
        self.subPanel2.add(label)
        self.subPanel2.add(self.emoticonFeedback)
        self.subPanel2.add(self.curseFeedback)
        self.subPanel2.add(self.styleFeedback)
        self.subPanel2.add(self.overallFeedback)
        
        self.mainPanel.add(self.subPanel1)
        self.mainPanel.add(self.subPanel2)
        
        
    def updateScores(self, event):
    	input = self.userText.getText()
    	scores = mes.get_scores(input)
    	overall = mes.get_overall_score()
    	
    	self.styleFeedback.setText("\n Your politeness score is "+str(scores['politeness'])
    								+".\n Higher is better. This is relative to the\n length of your email,"
    								+" so the more sentences you have,\n the higher this score should be.")
    								
        self.curseFeedback.setText(" You have about " +str(scores['curses'])+" curses in you email."
        								+"\n Please try to have 0 curses.")
        self.emoticonFeedback.setText(" You have about "+str(scores['emoticons'])+" emoticons in your email."
        								+"\n Fewer emoticons is considered more professional.")
        								
        self.overallFeedback.setText(" Your overall professionality score is "+str(overall)+"."
        							+"\n The baseline is around 50 for neutral emails."
        							+"\n Please remember that this is approximate.")
Esempio n. 8
0
class BurpExtender(IBurpExtender, ITab):
    THREAD_NUM = 20

    def registerExtenderCallbacks(self, callbacks):
        self.callbacks = callbacks
        self.helpers = callbacks.getHelpers()
        self.callbacks.setExtensionName("URLIMPORTER")
        self.threads = []

        self.__initLayout__()
        self.callbacks.addSuiteTab(self)

    def __initLayout__(self):
        self.panel = JPanel()
        self.panel.setLayout(FlowLayout())
        self.panel.setBounds(40, 80, 200, 200)
        self.UI_URLS_AREA = JTextArea('', 14, 80)
        self.UI_URLS_AREA.setLineWrap(True)
        self.UI_URLS_AREA_SCROLL = JScrollPane(self.UI_URLS_AREA)

        self.UI_HEADERS = JTextArea('', 8, 50)
        self.UI_HEADERS.setLineWrap(True)
        self.UI_HEADERS_AREA_SCROLL = JScrollPane(self.UI_HEADERS)

        self.url_add_to_sitemap_button = JButton(
            "ADD TO SITEMAP", actionPerformed=self.URLS_ADD_TO_SITEMAP)

        self.UI_HEADERS.setText(
            "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
        )
        self.panel.add(self.url_add_to_sitemap_button)
        self.panel.add(self.UI_URLS_AREA_SCROLL)
        self.panel.add(self.UI_HEADERS_AREA_SCROLL)

    def getTabCaption(self):
        return "CimexURLImport"

    def getUiComponent(self):
        return self.panel

    def URLS_ADD_TO_SITEMAP(self, event):
        self.q = queue.Queue()
        get_all_urls = self.UI_URLS_AREA.getText()
        get_headers = self.UI_HEADERS.getText()
        self.HEADERS = list(set(get_headers.split('\n')))
        urls_list = list(set(get_all_urls.split('\n')))

        for url in urls_list:
            url = url.rstrip()
            self.q.put(url)

        for j in range(self.THREAD_NUM):
            t = threading.Thread(target=self.ProcessQueue)
            self.threads.append(t)
            t.start()

    def ProcessQueue(self):
        while not self.q.empty():
            each_url = self.q.get()
            self.ProcessURL(each_url)
            self.q.task_done()

    def URL_SPLITTER(self, url):
        URL_SPLIT = str(url).split("://", 1)
        URL_PROTOCAL = URL_SPLIT[0]
        if URL_PROTOCAL == 'https':
            URL_PORT = 443
        elif URL_PROTOCAL == 'http':
            URL_PORT = 80
        else:
            URL_PORT = 443
        URL_HOSTNAME = URL_SPLIT[1].split('/', 1)[0].split('?', 1)[0]
        if ':' in URL_HOSTNAME:
            URL_HOSTNAME_FOR_SPLIT = URL_HOSTNAME
            URL_HOSTNAME = URL_HOSTNAME_FOR_SPLIT.split(':')[0]
            URL_PORT = int(URL_HOSTNAME_FOR_SPLIT.split(':')[1])
        URL_HOST_FULL = URL_PROTOCAL + "://" + URL_HOSTNAME
        try:
            URL_HOST_SERVICE = self.helpers.buildHttpService(
                URL_HOSTNAME, URL_PORT, URL_PROTOCAL)
        except java.lang.IllegalArgumentException:
            print("EXCEPTION BECAUSE HTTPSERVICE VALUES IS INVALID : {} : ".
                  format(url))
            print("EXCEPTION VALUES ARE :", URL_HOSTNAME, URL_PORT,
                  URL_PROTOCAL)
        return URL_SPLIT, URL_PROTOCAL, URL_HOSTNAME, URL_PORT, URL_HOST_FULL, URL_HOST_SERVICE

    def ProcessURL(self, url):
        print(url)
        if url.startswith('http://') or url.startswith('https://'):
            URL_SPLIT, URL_PROTOCAL, URL_HOSTNAME, URL_PORT, URL_HOST_FULL, URL_HOST_SERVICE = self.URL_SPLITTER(
                url)
            try:
                HEADERS = [
                    "GET /" + str(URL_SPLIT[1].split('/', 1)[1]) + " HTTP/1.1",
                    'Host: ' + str(URL_HOSTNAME)
                ]
            except:
                print("URL EXCEPTION IN HEADERS : {} : {}".format(
                    url, URL_SPLIT))
            if self.HEADERS:
                for each_header in self.HEADERS:
                    if each_header not in HEADERS:
                        HEADERS.append(each_header)
            msg = self.helpers.buildHttpMessage(HEADERS, None)
            resp = self.callbacks.makeHttpRequest(URL_HOST_SERVICE, msg)
            if resp.getResponse() != None:
                resp_analyze = self.helpers.analyzeResponse(resp.getResponse())
                self.callbacks.addToSiteMap(
                    resp)  ###! Adding Redirecting Request too in sitemap....
                resp_heads = resp_analyze.getHeaders()
                if '301' in resp_heads[0] or 'Moved' in resp_heads[
                        1] or '307' in resp_heads[0] or '302' in resp_heads[0]:
                    for each_head in resp_heads:
                        if each_head.startswith(
                                'Location:') or each_head.startswith(
                                    'location:'):
                            location_value = each_head.split(":",
                                                             1)[1].strip(' ')
                            if location_value.startswith('http'):
                                URL_SPLIT, URL_PROTOCAL, URL_HOSTNAME, URL_PORT, URL_HOST_FULL, URL_HOST_SERVICE = self.URL_SPLITTER(
                                    location_value)
                                try:
                                    HEADERS = [
                                        "GET /" +
                                        str(URL_SPLIT[1].split('/', 1)[1]) +
                                        " HTTP/1.1",
                                        'Host: ' + str(URL_HOSTNAME)
                                    ]
                                except:
                                    print(
                                        "URL EXCEPTION IN REDIRECTION HEADERS : {}"
                                        .format(URL_SPLIT))
                                    return False
                                if self.HEADERS:
                                    for each_header in self.HEADERS:
                                        if each_header not in HEADERS:
                                            HEADERS.append(each_header)
                            elif location_value.startswith('/'):
                                HEADERS = [
                                    "GET " + str(location_value) + " HTTP/1.1",
                                    'Host: ' + str(URL_HOSTNAME)
                                ]
                                if self.HEADERS:
                                    for each_header in self.HEADERS:
                                        if each_header not in HEADERS:
                                            HEADERS.append(each_header)
                            else:
                                pass
                            msg = self.helpers.buildHttpMessage(HEADERS, None)
                            resp = self.callbacks.makeHttpRequest(
                                URL_HOST_SERVICE, msg)
                            self.callbacks.addToSiteMap(resp)
Esempio n. 9
0
class ChatClient(JFrame):
	
	##  Constructor method, receives the variables from the ChatApp class as parameters
	
	def __init__(self, name, greeting, tn):
		'''Constructor, initialises base class & assigns variables
		'''
		# Call to the super method to take care of the base class(es)
		super(ChatClient, self).__init__()
		#  Assign the relevent variable names
		self.username=name
		self.greeting=greeting
		self.tn = tn
		self.no_users=[]
		#  Initiate the Threaded function for receiving messages
		t1=Thread(target=self.recvFunction)
		#  Set to daemon 
		t1.daemon=True
		t1.start()
		#Call the main UI
		uI=self.clientUI()
		
	##  Main GUI building function
	
	def clientUI(self):
		'''ClientUI and Widget creation
		'''
		#  Colours
		foreground_colour = Color(30,57,68)
		background_colour = Color(247,246,242)
		window_background = Color(145,190,210)
		#  Borders
		self.border2=BorderFactory.createLineBorder(foreground_colour,1, True)
		#  Fonts
		self.font= Font("Ubuntu Light",  Font.BOLD, 20)
		self.label_font= Font("Ubuntu Light",  Font.BOLD, 17)
		self.label_2_font= Font( "Ubuntu Light",Font.BOLD, 12)
		self.btn_font=Font("Ubuntu Light", Font.BOLD, 15)
		
		#  Set the layout parameters
		self.client_layout=GroupLayout(self.getContentPane())
		self.getContentPane().setLayout(self.client_layout)	
		self.getContentPane().setBackground(window_background)
		self.client_layout.setAutoCreateGaps(True)
		self.client_layout.setAutoCreateContainerGaps(True)
		self.setPreferredSize(Dimension(400, 450))
		
		#  Create widgets and assemble the GUI
		#  Main display area
		self.main_content=JTextPane()
		self.main_content.setBackground(background_colour)
		#self.main_content.setForeground(foreground_colour)
		self.main_content.setEditable(False)
		#  Message entry area  		
		self.message=JTextArea( 2,2, border=self.border2, font=self.label_font, keyPressed=self.returnKeyPress)
		self.message.requestFocusInWindow()	
		self.message.setBackground(background_colour)
		self.message.setForeground(foreground_colour)
		self.message.setLineWrap(True)
		self.message.setWrapStyleWord(True)
		self.message.setBorder(BorderFactory.createEmptyBorder(3,3,3,3))
		self.message.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), self.returnKeyPress) 
		#  BUttons
		quit_btn=JButton("Quit!", actionPerformed=ChatApp().closeEvent, border=self.border2, font=self.btn_font)
		go_btn=JButton("Send", actionPerformed=self.grabText, border=self.border2, font=self.btn_font)
		quit_btn.setBackground(background_colour)
		go_btn.setBackground(background_colour)
		quit_btn.setForeground(foreground_colour)
		go_btn.setForeground(foreground_colour)
		
		# Make scrollable
		self.scroll_content=JScrollPane(self.main_content)
		self.scroll_content.setPreferredSize(Dimension(150,275))
		self.scroll_content.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER)
		self.scroll_content.setViewportView(self.main_content)
		self.scroll_content.setBackground(Color.WHITE)
		self.scroll_message=JScrollPane(self.message)
		self.scroll_message.setPreferredSize(Dimension(150,20))
		self.scroll_message.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS)
		
		# Test user label, still not updating after first round of messages
		self.user_label=JLabel(" Users online : %s "%(str(len(self.no_users))),JLabel.RIGHT, font=self.label_2_font)
		
		#  Assemble the components
		#  Horizontal layout
		self.client_layout.setHorizontalGroup(self.client_layout.createParallelGroup()
				.addComponent(self.scroll_content)
				.addGroup(self.client_layout.createParallelGroup(GroupLayout.Alignment.CENTER)
					.addComponent(self.scroll_message))
				.addGroup(self.client_layout.createSequentialGroup()
					.addComponent(quit_btn)
					.addComponent(go_btn).addGap(20))
				.addGroup(self.client_layout.createParallelGroup()
					.addComponent(self.user_label))
		)
		
		#  Vertical layout
		self.client_layout.setVerticalGroup(self.client_layout.createSequentialGroup()
			.addGroup(self.client_layout.createParallelGroup()
				.addComponent(self.scroll_content))
				.addComponent(self.scroll_message)
				.addGroup(self.client_layout.createParallelGroup()
					.addComponent(quit_btn)
					.addComponent(go_btn))
				.addGroup(self.client_layout.createParallelGroup()
					.addComponent(self.user_label))
		)
		
		#  Finalise the GUI
		self.client_layout.linkSize(SwingConstants.HORIZONTAL, [quit_btn,go_btn, self.user_label])
		self.pack()
		self.message.requestFocusInWindow()
		self.setTitle(">>>   Client %s   <<<"%self.username)
		self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
		self.setLocationRelativeTo(None)
		self.setVisible(True)
		#  Display the server greeting
		self.appendText('\n'+self.greeting+'\n')
	
			
	##  Function responsible for receiving and processing new messages
	
	def recvFunction(self):
		'''A function to control the receiving of data from the connection
		'''
		#  While the connection is available
		while self.tn:
			#  Try to receive data using "<<<" as the delimiter
			try:
				message = self.tn.read_until('<<<')
				#  If a message is received
				if message:
					garb, message=message.split('>>>')
					message, garb = message.split('<<<')
					message = ('\n'+message+'\n')
					#  Call the append text function
					self.appendText(message)
			#  Except if there is no data available		
			except:
				#print('No message')	
				pass
	##  Event driven function to retrieve and send data to the server
	
	def grabText(self, event): 
		'''Function to repeatedly grab new messages entered into the text 
		area and display them in the main text area. Resets the entry area
		'''
		#  Grab the text from the text area
		text=self.message.getText()
		#  Don't allow an empty string through
		if text=='':
			return
		text=text.strip()
		#  Call the append text function
		self.appendText('\nYou : '+text+'\n', self.username)
		#  Reset the text to be empty and grab focus so that it is ready for new text input
		self.message.requestFocusInWindow()
		self.message.setText('')
		#  Send the message to the server
		data=text.encode()
		self.tn.write(data+'\r\n')

	##  Function to handle appending of messages
	
	def appendText(self, message, user=None):
		'''This function takes care of appending any new messages to the content area
		'''
		message_label=JTextArea(message,2,3, font=self.label_2_font)
		#  If this is a message from the grab text function, create a new label, assign it's colours
		if user!=None:
			message_label.setBackground(Color(240,240,240))
			message_label.setForeground(Color(129,129,129))
		#  Otherwise set the format for receive function (no user passed in)	
		else:
			message_label.setBackground(Color(215,215,215))
			message_label.setForeground(Color(40,153,153))
		
		#  Format and style options for the new message labels	
		message_label.setEditable(False)
		message_label.setLineWrap(True)
		message_label.setWrapStyleWord(True)
		message_label.setBorder(BorderFactory.createLineBorder( Color(247,246,242),4))
		#  Sets the positioning of messages
		self.main_content.setCaretPosition(self.main_content.getDocument().getLength())
		doc = self.main_content.getStyledDocument()
		attr=SimpleAttributeSet()
		self.main_content.insertComponent(message_label)
		# Essential for jtextarea to be able to stack message
		doc.insertString( self.main_content.getDocument().getLength(),'\n ', attr)
		# Not sure if needed
		self.main_content.repaint()
		
		###  This is a late edit so it isn't included in the documentation. Basically trying to dynamically update the number
		###  of users label at runtime. Works for incrementing the value but not decrementing it.
		
		print(message)
		#  Only split the message if there are enough values to split (greeting messages differ in format to chat messages)
		try:
			user, text=message.split(' : ')
		except:
			return
			
		#print('Split values are %s %s'%(user, text))
		user=str(user.strip())
		#print(self.no_users)
		#print(user+' : '+text)
		#  If the user already in the list, pass
		if user in self.no_users:
			if text == ('User %s amach sa teach !'%user):
				self.no_users.remove(user)
				print('User % removed'%user)
			
		else:
			#print('User %s not in list'%user)
			if str(user) == 'You':
				#print('User is equal to "You"')
				return 
			self.no_users.append(user)
			print('User appended')
			self.number_users=len(self.no_users)
			#print('Length of user list is '+str(self.number_users))
	
		self.user_label2=JLabel(" Users online : %s "%str(len(self.no_users)),JLabel.RIGHT, font=self.label_2_font)
		#print('Label created')
		#print('Attempt to replace label')
		self.client_layout.replace(self.user_label, self.user_label2) 
		self.user_label = self.user_label2
		self.user_label.repaint()
		self.user_label.revalidate()
		print('Label updated')
	
	##  Function to control return button press in message field

	def returnKeyPress(self,event):
		'''This function creates an object for return key press when inside the message entry area,
		creates an object of KeyAdapter and tests keycode for a match, responds with grab text callback		
		'''
		key_object=Key()
		key_value=key_object.keyPressed(event)
		if key_value == 10:
			self.grabText(event)
Esempio n. 10
0
class Config(ITab):
    """Defines the Configuration tab"""

    def __init__(self, callbacks, parent):
        # Initialze self stuff
        self._callbacks = callbacks
        self.config = {}
        self.ext_stats = {}
        self.url_reqs = []
        self.parse_files = False
        self.tab = JPanel(GridBagLayout())
        self.view_port_text = JTextArea("===SpyDir===")
        self.delim = JTextField(30)
        self.ext_white_list = JTextField(30)
        # I'm not sure if these fields are necessary still
        # why not just use Burp func to handle this?
        # leaving them in case I need it for the HTTP handler later
        # self.cookies = JTextField(30)
        # self.headers = JTextField(30)
        self.url = JTextField(30)
        self.parent_window = parent
        self.plugins = {}
        self.loaded_p_list = set()
        self.loaded_plugins = False
        self.config['Plugin Folder'] = None
        self.double_click = False
        self.source_input = ""
        self.print_stats = True
        self.curr_conf = JLabel()
        self.window = JFrame("Select plugins",
                             preferredSize=(200, 250),
                             windowClosing=self.p_close)
        self.window.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE)
        self.window.setVisible(False)
        self.path_vars = JTextField(30)


        # Initialize local stuff
        tab_constraints = GridBagConstraints()
        status_field = JScrollPane(self.view_port_text)

        # Configure view port
        self.view_port_text.setEditable(False)

        labels = self.build_ui()

        # Add things to rows
        tab_constraints.anchor = GridBagConstraints.FIRST_LINE_END
        tab_constraints.gridx = 1
        tab_constraints.gridy = 0
        tab_constraints.fill = GridBagConstraints.HORIZONTAL
        self.tab.add(JButton(
            "Resize screen", actionPerformed=self.resize),
                     tab_constraints)
        tab_constraints.gridx = 0
        tab_constraints.gridy = 1
        tab_constraints.anchor = GridBagConstraints.FIRST_LINE_START
        self.tab.add(labels, tab_constraints)

        tab_constraints.gridx = 1
        tab_constraints.gridy = 1
        tab_constraints.fill = GridBagConstraints.BOTH
        tab_constraints.weightx = 1.0
        tab_constraints.weighty = 1.0

        tab_constraints.anchor = GridBagConstraints.FIRST_LINE_END
        self.tab.add(status_field, tab_constraints)
        try:
            self._callbacks.customizeUiComponent(self.tab)
        except Exception:
            pass

    def build_ui(self):
        """Builds the configuration screen"""
        labels = JPanel(GridLayout(21, 1))
        checkbox = JCheckBox("Attempt to parse files for URL patterns?",
                             False, actionPerformed=self.set_parse)
        stats_box = JCheckBox("Show stats?", True,
                              actionPerformed=self.set_show_stats)
        # The two year old in me is laughing heartily
        plug_butt = JButton("Specify plugins location",
                            actionPerformed=self.set_plugin_loc)
        load_plug_butt = JButton("Select plugins",
                                 actionPerformed=self.p_build_ui)
        parse_butt = JButton("Parse directory", actionPerformed=self.parse)
        clear_butt = JButton("Clear text", actionPerformed=self.clear)
        spider_butt = JButton("Send to Spider", actionPerformed=self.scan)
        save_butt = JButton("Save config", actionPerformed=self.save)
        rest_butt = JButton("Restore config", actionPerformed=self.restore)
        source_butt = JButton("Input Source File/Directory",
                              actionPerformed=self.get_source_input)

        # Build grid
        labels.add(source_butt)
        labels.add(self.curr_conf)
        labels.add(JLabel("String Delimiter:"))
        labels.add(self.delim)
        labels.add(JLabel("Extension Whitelist:"))
        labels.add(self.ext_white_list)
        labels.add(JLabel("URL:"))
        labels.add(self.url)
        labels.add(JLabel("Path Variables"))
        labels.add(self.path_vars)
        # Leaving these here for now.
        # labels.add(JLabel("Cookies:"))
        # labels.add(self.cookies)
        # labels.add(JLabel("HTTP Headers:"))
        # labels.add(self.headers)
        labels.add(checkbox)
        labels.add(stats_box)
        labels.add(plug_butt)
        labels.add(parse_butt)
        labels.add(JButton("Show all endpoints",
                           actionPerformed=self.print_endpoints))
        labels.add(clear_butt)
        labels.add(spider_butt)
        labels.add(JLabel(""))
        labels.add(save_butt)
        labels.add(rest_butt)
        labels.add(load_plug_butt)
        # Tool tips!
        self.delim.setToolTipText("Use to manipulate the final URL. "
                                  "See About tab for example.")
        self.ext_white_list.setToolTipText("Define a comma delimited list of"
                                           " file extensions to parse. Use *"
                                           " to parse all files.")
        self.url.setToolTipText("Enter the target URL")
        checkbox.setToolTipText("Parse files line by line using plugins"
                                " to enumerate language/framework specific"
                                " endpoints")
        parse_butt.setToolTipText("Attempt to enumerate application endpoints")
        clear_butt.setToolTipText("Clear status window and the parse results")
        spider_butt.setToolTipText("Process discovered endpoints")
        save_butt.setToolTipText("Saves the current config settings")
        rest_butt.setToolTipText("<html>Restores previous config settings:"
                                 "<br/>-Input Directory<br/>-String Delim"
                                 "<br/>-Ext WL<br/>-URL<br/>-Plugins")
        source_butt.setToolTipText("Select the application's "
                                   "source directory or file to parse")
        self.path_vars.setToolTipText("Supply a JSON object with values"
                                      "for dynamically enumerated query"
                                      "string variables")

        return labels

    def set_url(self, menu_url):
        """Changes the configuration URL to the one from the menu event"""
        self.url.setText(menu_url)

    # Event functions
    def set_parse(self, event):
        """
        Handles the click event from the UI checkbox
        to attempt code level parsing
        """
        self.parse_files = not self.parse_files
        if self.parse_files:
            if not self.loaded_plugins:
                self._plugins_missing_warning()

    def restore(self, event):
        """Attempts to restore the previously saved configuration."""
        jdump = None
        try:
            jdump = loads(self._callbacks.loadExtensionSetting("config"))
        except Exception as exc:  # Generic exception thrown directly to user
            self.update_scroll(
                "[!!] Error during restore!\n\tException: %s" % str(exc))
        if jdump is not None:
            self.url.setText(jdump.get('URL'))
            # self.cookies.setText(jdump.get('Cookies'))
            # self.headers.setText(jdump.get("Headers"))
            ewl = ""
            for ext in jdump.get('Extension Whitelist'):
                ewl += ext + ", "
            self.ext_white_list.setText(ewl[:-2])
            self.delim.setText(jdump.get('String Delimiter'))
            self.source_input = jdump.get("Input Directory")
            self.config['Plugin Folder'] = jdump.get("Plugin Folder")
            if (self.config['Plugin Folder'] is not None and
                    (len(self.plugins.values()) < 1)):
                self._load_plugins(self.config['Plugin Folder'])
            self._update()
            self.update_scroll("[^] Restore complete!")
        else:
            self.update_scroll("[!!] Restore failed!")

    def save(self, event=None):
        """
        Saves the configuration details to a Burp Suite's persistent store.
        """
        self._update()
        try:
            if not self._callbacks.isInScope(URL(self.url.getText())):
                self.update_scroll("[!!] URL provided is NOT in Burp Scope!")
        except MalformedURLException:  # If url field is blank we'll
            pass                       # still save the settings.
        try:
            self._callbacks.saveExtensionSetting("config", dumps(self.config))
            self.update_scroll("[^] Settings saved!")
        except Exception:
            self.update_scroll("[!!] Error saving settings to Burp Suite!")

    def parse(self, event):
        """
        Handles the click event from the UI.
        Attempts to parse the given directory
            (and/or source files) for url endpoints
        Saves the items found within the url_reqs list
        """
        self._update()

        file_set = set()
        fcount = 0
        other_dirs = set()
        self.ext_stats = {}
        if self.loaded_plugins:
            self.update_scroll("[^] Attempting to parse files" +
                               " for URL patterns. This might take a minute.")
        if path.isdir(self.source_input):
            for dirname, _, filenames in walk(self.source_input):
                for filename in filenames:
                    fcount += 1
                    ext = path.splitext(filename)[1]
                    count = self.ext_stats.get(ext, 0) + 1
                    filename = "%s/%s" % (dirname, filename)
                    self.ext_stats.update({ext: count})
                    if self.parse_files and self._ext_test(ext):
                        # i can haz threading?
                        file_set.update(self._code_as_endpoints(filename, ext))
                    elif self._ext_test(ext):
                        r_files, oths = self._files_as_endpoints(filename, ext)
                        file_set.update(r_files)
                        other_dirs.update(oths)
        elif path.isfile(self.source_input):
            ext = path.splitext(self.source_input)[1]
            file_set.update(self._code_as_endpoints(self.source_input, ext))
        else:
            self.update_scroll("[!!] Input Directory is not valid!")
        if len(other_dirs) > 0:
            self.update_scroll("[*] Found files matching file extension in:\n")
            for other_dir in other_dirs:
                self.update_scroll(" " * 4 + "%s\n" % other_dir)
        self._handle_path_vars(file_set)
        self._print_parsed_status(fcount)
        return (other_dirs, self.url_reqs)

    def _handle_path_vars(self, file_set):
        proto = 'http://'
        for item in file_set:
            if item.startswith("http://") or item.startswith("https://"):
                proto = item.split("//")[0] + '//'
                item = item.replace(proto, "")
                item = self._path_vars(item)
            self.url_reqs.append(proto + item.replace('//', '/'))

    def _path_vars(self, item):
        p_vars = None
        if self.path_vars.getText():
            try:
                p_vars = loads(str(self.path_vars.getText()))
            except:
                self.update_scroll("[!] Error reading supplied Path Variables!")
        if p_vars is not None:
            rep_str = ""
            try:
                for k in p_vars.keys():
                    rep_str += "[^] Replacing %s with %s!\n" % (k, str(p_vars.get(k)))
                self.update_scroll(rep_str)
                for k in p_vars.keys():
                    if str(k) in item:
                        item = item.replace(k, str(p_vars.get(k)))
            except AttributeError:
                self.update_scroll("[!] Error reading supplied Path Variables! This needs to be a JSON dictionary!")
        return item
            
            
    def scan(self, event):
        """
        handles the click event from the UI.
        Adds the given URL to the burp scope and sends the requests
        to the burp spider
        """
        temp_url = self.url.getText()
        if not self._callbacks.isInScope(URL(temp_url)):
            if not self.double_click:
                self.update_scroll("[!!] URL is not in scope! Press Send to "
                                   "Spider again to add to scope and scan!")
                self.double_click = True
                return
            else:
                self._callbacks.sendToSpider(URL(temp_url))
        self.update_scroll(
            "[^] Sending %d requests to Spider" % len(self.url_reqs))
        for req in self.url_reqs:
            self._callbacks.sendToSpider(URL(req))

    def clear(self, event):
        """Clears the viewport and the current parse exts"""
        self.view_port_text.setText("===SpyDir===")
        self.ext_stats = {}

    def print_endpoints(self, event):
        """Prints the discovered endpoints to the status window."""
        req_str = ""
        if len(self.url_reqs) > 0:
            self.update_scroll("[*] Printing all discovered endpoints:")
            for req in sorted(self.url_reqs):
                req_str += "    %s\n" % req
        else:
            req_str = "[!!] No endpoints discovered"
        self.update_scroll(req_str)

    def set_show_stats(self, event):
        """Modifies the show stats setting"""
        self.print_stats = not self.print_stats

    def get_source_input(self, event):
        """Sets the source dir/file for parsing"""
        source_chooser = JFileChooser()
        source_chooser.setFileSelectionMode(
            JFileChooser.FILES_AND_DIRECTORIES)
        source_chooser.showDialog(self.tab, "Choose Source Location")
        chosen_source = source_chooser.getSelectedFile()
        try:
            self.source_input = chosen_source.getAbsolutePath()
        except AttributeError:
            pass
        if self.source_input is not None:
            self.update_scroll("[*] Source location: %s" % self.source_input)
            self.curr_conf.setText(self.source_input)

    # Plugin functions
    def _parse_file(self, filename, file_url):
        """
        Attempts to parse a file with the loaded plugins
        Returns set of endpoints
        """
        file_set = set()
        with open(filename, 'r') as plug_in:
            lines = plug_in.readlines()
        ext = path.splitext(filename)[1].upper()
        if ext in self.plugins.keys() and self._ext_test(ext):
            for plug in self.plugins.get(ext):
                if plug.enabled:
                    res = plug.run(lines)
                    if len(res) > 0:
                        for i in res:
                            i = file_url + i
                            file_set.add(i)
        elif ext == '.TXT' and self._ext_test(ext):
            for i in lines:
                i = file_url + i
                file_set.add(i.strip())
        return file_set

    def set_plugin_loc(self, event):
        """Attempts to load plugins from a specified location"""
        if self.config['Plugin Folder'] is not None:
            choose_plugin_location = JFileChooser(self.config['Plugin Folder'])
        else:
            choose_plugin_location = JFileChooser()
        choose_plugin_location.setFileSelectionMode(
            JFileChooser.DIRECTORIES_ONLY)
        choose_plugin_location.showDialog(self.tab, "Choose Folder")
        chosen_folder = choose_plugin_location.getSelectedFile()
        self.config['Plugin Folder'] = chosen_folder.getAbsolutePath()
        self._load_plugins(self.config['Plugin Folder'])

    def _load_plugins(self, folder):
        """
        Parses a local directory to get the plugins
            related to code level scanning
        """
        report = ""
        if len(self.plugins.keys()) > 0:
            report = "[^] Plugins reloaded!"
        for _, _, filenames in walk(folder):
            for p_name in filenames:
                n_e = path.splitext(p_name)  # n_e = name_extension
                if n_e[1] == ".py":
                    f_loc = "%s/%s" % (folder, p_name)
                    loaded_plug = self._validate_plugin(n_e[0], f_loc)
                    if loaded_plug:
                        for p in self.loaded_p_list:
                            if p.get_name() == loaded_plug.get_name():
                                self.loaded_p_list.discard(p)
                        self.loaded_p_list.add(loaded_plug)
                        if not report.startswith("[^]"):
                            report += "%s loaded\n" % loaded_plug.get_name()

        self._dictify(self.loaded_p_list)
        if len(self.plugins.keys()) > 0:
            self.loaded_plugins = True
        else:
            report = "[!!] Plugins load failure"
            self.loaded_plugins = False
        self.update_scroll(report)
        return report

    def _validate_plugin(self, p_name, f_loc):
        """
        Attempts to verify the manditory plugin functions to prevent broken
        plugins from loading.
        Generates an error message if plugin does not contain an appropriate
        function.
        """
        # Load the plugin
        try:
            plug = load_source(p_name, f_loc)
        except Exception as exc:  # this needs to be generic.
            self.update_scroll(
                "[!!] Error loading: %s\n\tType:%s Error: %s"
                % (f_loc, type(exc), str(exc)))
        # Verify the plugin's functions
        funcs = dir(plug)
        err = []
        if "get_name" not in funcs:
            err.append("get_name()")
        if "get_ext" not in funcs:
            err.append("get_ext()")
        if "run" not in funcs:
            err.append("run()")

        # Report errors & return
        if len(err) < 1:
            return Plugin(plug, True)
        for issue in err:
            self.update_scroll("[!!] %s is missing: %s func" %
                               (p_name, issue))
        return None

    def _dictify(self, plist):
        """Converts the list of loaded plugins (plist) into a dictionary"""
        for p in plist:
            exts = p.get_ext().upper()
            for ext in exts.split(","):
                prev_load = self.plugins.get(ext, [])
                prev_load.append(p)
                self.plugins[ext] = prev_load

    # Status window functions
    def _print_parsed_status(self, fcount):
        """Prints the parsed directory status information"""
        if self.parse_files and not self.loaded_plugins:
            self._plugins_missing_warning()
        if len(self.url_reqs) > 0:
            self.update_scroll("[*] Example URL: %s" % self.url_reqs[0])

        if self.print_stats:
            report = (("[*] Found: %r files to be requested.\n\n" +
                       "[*] Stats: \n    " +
                       "Found: %r files.\n") % (len(self.url_reqs), fcount))
            if len(self.ext_stats) > 0:
                report += ("[*] Extensions found: %s"
                           % str(dumps(self.ext_stats,
                                       sort_keys=True, indent=4)))
        else:
            report = ("[*] Found: %r files to be requested.\n" %
                      len(self.url_reqs))
        self.update_scroll(report)
        return report

    def _plugins_missing_warning(self):
        """Prints a warning message"""
        self.update_scroll("[!!] No plugins loaded!")

    def update_scroll(self, text):
        """Updates the view_port_text with the new information"""
        temp = self.view_port_text.getText().strip()
        if text not in temp or text[0:4] == "[!!]":
            self.view_port_text.setText("%s\n%s" % (temp, text))
        elif not temp.endswith("[^] Status unchanged"):
            self.view_port_text.setText("%s\n[^] Status unchanged" % temp)

    # Internal functions
    def _code_as_endpoints(self, filename, ext):
        file_set = set()
        file_url = self.config.get("URL")
        if self.loaded_plugins or ext == '.txt':
            if self._ext_test(ext):
                file_set.update(
                    self._parse_file(filename, file_url))
            else:
                file_set.update(
                    self._parse_file(filename, file_url))
        return file_set

    def _files_as_endpoints(self, filename, ext):
        """Generates endpoints via files with the appropriate extension(s)"""
        file_url = self.config.get("URL")
        broken_splt = ""
        other_dirs = set()  # directories outside of the String Delim.
        file_set = set()
        str_del = self.config.get("String Delimiter")
        if not str_del:
            self.update_scroll("[!!] No available String Delimiter!")
            return
        spl_str = filename.split(str_del)

        try:
            # Fix for index out of bounds exception while parsing
            # subfolders _not_ included by the split
            if len(spl_str) > 1:
                file_url += ((spl_str[1])
                             .replace('\\', '/'))
            else:
                broken_splt = filename.split(self.source_input)[1]
                other_dirs.add(broken_splt)
        except Exception as exc:  # Generic exception thrown directly to user
            self.update_scroll("[!!] Error parsing: " +
                               "%s\n\tException: %s"
                               % (filename, str(exc)))
        if self._ext_test(ext):
            if file_url != self.config.get("URL"):
                file_set.add(file_url)
        else:
            other_dirs.discard(broken_splt)
        return file_set, other_dirs

    def _ext_test(self, ext):
        """Litmus test for extension whitelist"""
        val = False
        if "*" in self.config.get("Extension Whitelist"):
            val = True
        else:
            val = (len(ext) > 0 and
                   (ext.strip().upper()
                    in self.config.get("Extension Whitelist")))
        return val

    def _update(self):
        """Updates internal data"""
        self.config["Input Directory"] = self.source_input
        self.config["String Delimiter"] = self.delim.getText()

        white_list_text = self.ext_white_list.getText()
        self.config["Extension Whitelist"] = white_list_text.upper().split(',')
        file_url = self.url.getText()
        if not (file_url.startswith('https://') or file_url.startswith('http://')):
            self.update_scroll("[!] Assuming protocol! Default value: 'http://'")
            file_url = 'http://' + file_url
            self.url.setText(file_url)

        if not file_url.endswith('/') and file_url != "":
            file_url += '/'

        self.config["URL"] = file_url
        # self.config["Cookies"] = self.cookies.getText()
        # self.config["Headers"] = self.headers.getText()
        del self.url_reqs[:]
        self.curr_conf.setText(self.source_input)

    # Window sizing functions
    def resize(self, event):
        """Resizes the window to better fit Burp"""
        if self.parent_window is not None:
            par_size = self.parent_window.getSize()
            par_size.setSize(par_size.getWidth() * .99,
                             par_size.getHeight() * .9)
            self.tab.setPreferredSize(par_size)
            self.parent_window.validate()
            self.parent_window.switch_focus()

    def p_close(self, event):
        """
        Handles the window close event.
        """
        self.window.setVisible(False)
        self.window.dispose()

    def p_build_ui(self, event):
        """
        Adds a list of checkboxes, one for each loaded plugin
        to the Selct plugins window
        """
        if not self.loaded_p_list:
            self.update_scroll("[!!] No plugins loaded!")
            return

        scroll_pane = JScrollPane()
        scroll_pane.setPreferredSize(Dimension(200, 250))
        check_frame = JPanel(GridBagLayout())
        constraints = GridBagConstraints()
        constraints.fill = GridBagConstraints.HORIZONTAL
        constraints.gridy = 0
        constraints.anchor = GridBagConstraints.FIRST_LINE_START

        for plug in self.loaded_p_list:
            check_frame.add(JCheckBox(plug.get_name(), plug.enabled,
                                      actionPerformed=self.update_box),
                            constraints)
            constraints.gridy += 1

        vport = JViewport()
        vport.setView(check_frame)
        scroll_pane.setViewport(vport)
        self.window.contentPane.add(scroll_pane)
        self.window.pack()
        self.window.setVisible(True)

    def update_box(self, event):
        """
        Handles the check/uncheck event for the plugin's box.
        """
        for plug in self.loaded_p_list:
            if plug.get_name() == event.getActionCommand():
                plug.enabled = not plug.enabled
                if plug.enabled:
                    self.update_scroll("[^] Enabled: %s" %
                                       event.getActionCommand())
                else:
                    self.update_scroll("[^] Disabled: %s" %
                                       event.getActionCommand())

    # ITab required functions
    @staticmethod
    def getTabCaption():
        """Returns the name of the Burp Suite Tab"""
        return "SpyDir"

    def getUiComponent(self):
        """Returns the UI component for the Burp Suite tab"""
        return self.tab
Esempio n. 11
0
class Config(ITab):
    """Defines the Configuration tab"""

    def __init__(self, callbacks, parent):
        # Initialze self stuff
        self._callbacks = callbacks
        self.config = {}
        self.ext_stats = {}
        self.url_reqs = []
        self.parse_files = False
        self.tab = JPanel(GridBagLayout())
        self.view_port_text = JTextArea("===SpyDir===")
        self.delim = JTextField(30)
        self.ext_white_list = JTextField(30)
        # I'm not sure if these fields are necessary still
        # why not just use Burp func to handle this?
        # leaving them in case I need it for the HTTP handler later
        # self.cookies = JTextField(30)
        # self.headers = JTextField(30)
        self.url = JTextField(30)
        self.parent_window = parent
        self.plugins = {}
        self.loaded_p_list = set()
        self.loaded_plugins = False
        self.config['Plugin Folder'] = None
        self.double_click = False
        self.source_input = ""
        self.print_stats = True
        self.curr_conf = JLabel()
        self.window = JFrame("Select plugins",
                             preferredSize=(200, 250),
                             windowClosing=self.p_close)
        self.window.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE)
        self.window.setVisible(False)

        # Initialize local stuff
        tab_constraints = GridBagConstraints()
        status_field = JScrollPane(self.view_port_text)

        # Configure view port
        self.view_port_text.setEditable(False)

        labels = self.build_ui()

        # Add things to rows
        tab_constraints.anchor = GridBagConstraints.FIRST_LINE_END
        tab_constraints.gridx = 1
        tab_constraints.gridy = 0
        tab_constraints.fill = GridBagConstraints.HORIZONTAL
        self.tab.add(JButton(
            "Resize screen", actionPerformed=self.resize),
                     tab_constraints)
        tab_constraints.gridx = 0
        tab_constraints.gridy = 1
        tab_constraints.anchor = GridBagConstraints.FIRST_LINE_START
        self.tab.add(labels, tab_constraints)

        tab_constraints.gridx = 1
        tab_constraints.gridy = 1
        tab_constraints.fill = GridBagConstraints.BOTH
        tab_constraints.weightx = 1.0
        tab_constraints.weighty = 1.0

        tab_constraints.anchor = GridBagConstraints.FIRST_LINE_END
        self.tab.add(status_field, tab_constraints)
        try:
            self._callbacks.customizeUiComponent(self.tab)
        except Exception:
            pass

    def build_ui(self):
        """Builds the configuration screen"""
        labels = JPanel(GridLayout(21, 1))
        checkbox = JCheckBox("Attempt to parse files for URL patterns?",
                             False, actionPerformed=self.set_parse)
        stats_box = JCheckBox("Show stats?", True,
                              actionPerformed=self.set_show_stats)
        # The two year old in me is laughing heartily
        plug_butt = JButton("Specify plugins location",
                            actionPerformed=self.set_plugin_loc)
        load_plug_butt = JButton("Select plugins",
                                 actionPerformed=self.p_build_ui)
        parse_butt = JButton("Parse directory", actionPerformed=self.parse)
        clear_butt = JButton("Clear text", actionPerformed=self.clear)
        spider_butt = JButton("Send to Spider", actionPerformed=self.scan)
        save_butt = JButton("Save config", actionPerformed=self.save)
        rest_butt = JButton("Restore config", actionPerformed=self.restore)
        source_butt = JButton("Input Source File/Directory",
                              actionPerformed=self.get_source_input)

        # Build grid
        labels.add(source_butt)
        labels.add(self.curr_conf)
        labels.add(JLabel("String Delimiter:"))
        labels.add(self.delim)
        labels.add(JLabel("Extension Whitelist:"))
        labels.add(self.ext_white_list)
        labels.add(JLabel("URL:"))
        labels.add(self.url)
        # Leaving these here for now.
        # labels.add(JLabel("Cookies:"))
        # labels.add(self.cookies)
        # labels.add(JLabel("HTTP Headers:"))
        # labels.add(self.headers)
        labels.add(checkbox)
        labels.add(stats_box)
        labels.add(plug_butt)
        labels.add(parse_butt)
        labels.add(JButton("Show all endpoints",
                           actionPerformed=self.print_endpoints))
        labels.add(clear_butt)
        labels.add(spider_butt)
        labels.add(JLabel(""))
        labels.add(save_butt)
        labels.add(rest_butt)
        labels.add(load_plug_butt)
        # Tool tips!
        self.delim.setToolTipText("Use to manipulate the final URL. "
                                  "See About tab for example.")
        self.ext_white_list.setToolTipText("Define a comma delimited list of"
                                           " file extensions to parse. Use *"
                                           " to parse all files.")
        self.url.setToolTipText("Enter the target URL")
        checkbox.setToolTipText("Parse files line by line using plugins"
                                " to enumerate language/framework specific"
                                " endpoints")
        parse_butt.setToolTipText("Attempt to enumerate application endpoints")
        clear_butt.setToolTipText("Clear status window and the parse results")
        spider_butt.setToolTipText("Process discovered endpoints")
        save_butt.setToolTipText("Saves the current config settings")
        rest_butt.setToolTipText("<html>Restores previous config settings:"
                                 "<br/>-Input Directory<br/>-String Delim"
                                 "<br/>-Ext WL<br/>-URL<br/>-Plugins")
        source_butt.setToolTipText("Select the application's "
                                   "source directory or file to parse")

        return labels

    def set_url(self, menu_url):
        """Changes the configuration URL to the one from the menu event"""
        self.url.setText(menu_url)

    # Event functions
    def set_parse(self, event):
        """
        Handles the click event from the UI checkbox
        to attempt code level parsing
        """
        self.parse_files = not self.parse_files
        if self.parse_files:
            if not self.loaded_plugins:
                self._plugins_missing_warning()

    def restore(self, event):
        """Attempts to restore the previously saved configuration."""
        jdump = None
        try:
            jdump = loads(self._callbacks.loadExtensionSetting("config"))
        except Exception as exc:  # Generic exception thrown directly to user
            self.update_scroll(
                "[!!] Error during restore!\n\tException: %s" % str(exc))
        if jdump is not None:
            self.url.setText(jdump.get('URL'))
            # self.cookies.setText(jdump.get('Cookies'))
            # self.headers.setText(jdump.get("Headers"))
            ewl = ""
            for ext in jdump.get('Extension Whitelist'):
                ewl += ext + ", "
            self.ext_white_list.setText(ewl[:-2])
            self.delim.setText(jdump.get('String Delimiter'))
            self.source_input = jdump.get("Input Directory")
            self.config['Plugin Folder'] = jdump.get("Plugin Folder")
            if (self.config['Plugin Folder'] is not None and
                    (len(self.plugins.values()) < 1)):
                self._load_plugins(self.config['Plugin Folder'])
            self._update()
            self.update_scroll("[^] Restore complete!")
        else:
            self.update_scroll("[!!] Restore failed!")

    def save(self, event=None):
        """
        Saves the configuration details to a Burp Suite's persistent store.
        """
        self._update()
        try:
            if not self._callbacks.isInScope(URL(self.url.getText())):
                self.update_scroll("[!!] URL provided is NOT in Burp Scope!")
        except MalformedURLException:  # If url field is blank we'll
            pass                       # still save the settings.

        try:
            self._callbacks.saveExtensionSetting("config", dumps(self.config))
            self.update_scroll("[^] Settings saved!")
        except Exception:
            self.update_scroll("[!!] Error saving settings to Burp Suite!")

    def parse(self, event):
        """
        Handles the click event from the UI.
        Attempts to parse the given directory
            (and/or source files) for url endpoints
        Saves the items found within the url_reqs list
        """
        self._update()

        file_set = set()
        fcount = 0
        other_dirs = set()
        self.ext_stats = {}
        if self.loaded_plugins:
            self.update_scroll("[^] Attempting to parse files" +
                               " for URL patterns. This might take a minute.")
        if path.isdir(self.source_input):
            for dirname, _, filenames in walk(self.source_input):
                for filename in filenames:
                    fcount += 1
                    ext = path.splitext(filename)[1]
                    count = self.ext_stats.get(ext, 0) + 1
                    filename = "%s/%s" % (dirname, filename)
                    self.ext_stats.update({ext: count})
                    if self.parse_files:
                        # i can haz threading?
                        file_set.update(self._code_as_endpoints(filename, ext))
                    elif self._ext_test(ext):
                        r_files, oths = self._files_as_endpoints(filename, ext)
                        file_set.update(r_files)
                        other_dirs.update(oths)
        elif path.isfile(self.source_input):
            ext = path.splitext(self.source_input)[1]
            file_set.update(self._code_as_endpoints(self.source_input, ext))
        else:
            self.update_scroll("[!!] Input Directory is not valid!")
        if len(other_dirs) > 0:
            self.update_scroll("[*] Found files matching file extension in:\n")
            for other_dir in other_dirs:
                self.update_scroll(" " * 4 + "%s\n" % other_dir)
        for item in file_set:
            if item.startswith("http://") or item.startswith("https://"):
                proto = item.split("//")[0] + '//'
                item = item.replace(proto, "")
            self.url_reqs.append(proto + item.replace('//', '/'))
        self._print_parsed_status(fcount)
        return (other_dirs, self.url_reqs)

    def scan(self, event):
        """
        handles the click event from the UI.
        Adds the given URL to the burp scope and sends the requests
        to the burp spider
        """
        temp_url = self.url.getText()
        if not self._callbacks.isInScope(URL(temp_url)):
            if not self.double_click:
                self.update_scroll("[!!] URL is not in scope! Press Send to "
                                   "Spider again to add to scope and scan!")
                self.double_click = True
                return
            else:
                self._callbacks.sendToSpider(URL(temp_url))
        self.update_scroll(
            "[^] Sending %d requests to Spider" % len(self.url_reqs))
        for req in self.url_reqs:
            self._callbacks.sendToSpider(URL(req))

    def clear(self, event):
        """Clears the viewport and the current parse exts"""
        self.view_port_text.setText("===SpyDir===")
        self.ext_stats = {}

    def print_endpoints(self, event):
        """Prints the discovered endpoints to the status window."""
        req_str = ""
        if len(self.url_reqs) > 0:
            self.update_scroll("[*] Printing all discovered endpoints:")
            for req in self.url_reqs:
                req_str += "    %s\n" % req
        else:
            req_str = "[!!] No endpoints discovered"
        self.update_scroll(req_str)

    def set_show_stats(self, event):
        """Modifies the show stats setting"""
        self.print_stats = not self.print_stats

    def get_source_input(self, event):
        """Sets the source dir/file for parsing"""
        source_chooser = JFileChooser()
        source_chooser.setFileSelectionMode(
            JFileChooser.FILES_AND_DIRECTORIES)
        source_chooser.showDialog(self.tab, "Choose Source Location")
        chosen_source = source_chooser.getSelectedFile()
        try:
            self.source_input = chosen_source.getAbsolutePath()
        except AttributeError:
            pass
        if self.source_input is not None:
            self.update_scroll("[*] Source location: %s" % self.source_input)
            self.curr_conf.setText(self.source_input)

    # Plugin functions
    def _parse_file(self, filename, file_url):
        """
        Attempts to parse a file with the loaded plugins
        Returns set of endpoints
        """
        file_set = set()
        with open(filename, 'r') as plug_in:
            lines = plug_in.readlines()
        ext = path.splitext(filename)[1].upper()
        if ext in self.plugins.keys():
            for plug in self.plugins.get(ext):
                if plug.enabled:
                    res = plug.run(lines)
                    if len(res) > 0:
                        for i in res:
                            i = file_url + i
                            file_set.add(i)
        elif ext == '.TXT' and self._ext_test(ext):
            for i in lines:
                i = file_url + i
                file_set.add(i.strip())
        return file_set

    def set_plugin_loc(self, event):
        """Attempts to load plugins from a specified location"""
        if self.config['Plugin Folder'] is not None:
            choose_plugin_location = JFileChooser(self.config['Plugin Folder'])
        else:
            choose_plugin_location = JFileChooser()
        choose_plugin_location.setFileSelectionMode(
            JFileChooser.DIRECTORIES_ONLY)
        choose_plugin_location.showDialog(self.tab, "Choose Folder")
        chosen_folder = choose_plugin_location.getSelectedFile()
        self.config['Plugin Folder'] = chosen_folder.getAbsolutePath()
        self._load_plugins(self.config['Plugin Folder'])

    def _load_plugins(self, folder):
        """
        Parses a local directory to get the plugins
            related to code level scanning
        """
        report = ""
        if len(self.plugins.keys()) > 0:
            report = "[^] Plugins reloaded!"
        for _, _, filenames in walk(folder):
            for p_name in filenames:
                n_e = path.splitext(p_name)  # n_e = name_extension
                if n_e[1] == ".py":
                    f_loc = "%s/%s" % (folder, p_name)
                    loaded_plug = self._validate_plugin(n_e[0], f_loc)
                    if loaded_plug:
                        self.loaded_p_list.add(loaded_plug)
                        if not report.startswith("[^]"):
                            report += "%s loaded\n" % loaded_plug.get_name()

        self._dictify(self.loaded_p_list)
        if len(self.plugins.keys()) > 0:
            self.loaded_plugins = True
        else:
            report = "[!!] Plugins load failure"
            self.loaded_plugins = False
        self.update_scroll(report)
        return report

    def _validate_plugin(self, p_name, f_loc):
        """
        Attempts to verify the manditory plugin functions to prevent broken
        plugins from loading.
        Generates an error message if plugin does not contain an appropriate
        function.
        """
        # Load the plugin
        try:
            plug = load_source(p_name, f_loc)
        except Exception as exc:  # this needs to be generic.
            self.update_scroll(
                "[!!] Error loading: %s\n\tType:%s Error: %s"
                % (f_loc, type(exc), str(exc)))
        # Verify the plugin's functions
        funcs = dir(plug)
        err = []
        if "get_name" not in funcs:
            err.append("get_name()")
        if "get_ext" not in funcs:
            err.append("get_ext()")
        if "run" not in funcs:
            err.append("run()")

        # Report errors & return
        if len(err) < 1:
            return Plugin(plug, True)
        else:
            for issue in err:
                self.update_scroll("[!!] %s is missing: %s func" %
                                   (p_name, issue))
            return None

    def _dictify(self, plist):
        """Converts the list of loaded plugins (plist) into a dictionary"""
        for p in plist:
            exts = p.get_ext().upper()
            for ext in exts.split(","):
                prev_load = self.plugins.get(ext, [])
                prev_load.append(p)
                self.plugins[ext] = prev_load

    # Status window functions
    def _print_parsed_status(self, fcount):
        """Prints the parsed directory status information"""
        if self.parse_files and not self.loaded_plugins:
            self._plugins_missing_warning()
        if len(self.url_reqs) > 0:
            self.update_scroll("[*] Example URL: %s" % self.url_reqs[0])

        if self.print_stats:
            report = (("[*] Found: %r files to be requested.\n\n" +
                       "[*] Stats: \n    " +
                       "Found: %r files.\n") % (len(self.url_reqs), fcount))
            if len(self.ext_stats) > 0:
                report += ("[*] Extensions found: %s"
                           % str(dumps(self.ext_stats,
                                       sort_keys=True, indent=4)))
        else:
            report = ("[*] Found: %r files to be requested.\n" %
                      len(self.url_reqs))
        self.update_scroll(report)
        return report

    def _plugins_missing_warning(self):
        """Prints a warning message"""
        self.update_scroll("[!!] No plugins loaded!")

    def update_scroll(self, text):
        """Updates the view_port_text with the new information"""
        temp = self.view_port_text.getText().strip()
        if text not in temp or text[0:4] == "[!!]":
            self.view_port_text.setText("%s\n%s" % (temp, text))
        elif not temp.endswith("[^] Status unchanged"):
            self.view_port_text.setText("%s\n[^] Status unchanged" % temp)

    # Internal functions
    def _code_as_endpoints(self, filename, ext):
        file_set = set()
        file_url = self.config.get("URL")
        if self.loaded_plugins:
            if self._ext_test(ext):
                file_set.update(
                    self._parse_file(filename, file_url))
            else:
                file_set.update(
                    self._parse_file(filename, file_url))
        return file_set

    def _files_as_endpoints(self, filename, ext):
        """Generates endpoints via files with the appropriate extension(s)"""
        file_url = self.config.get("URL")
        broken_splt = ""
        other_dirs = set()  # directories outside of the String Delim.
        file_set = set()
        str_del = self.config.get("String Delimiter")
        if not str_del:
            self.update_scroll("[!!] No available String Delimiter!")
            return
        spl_str = filename.split(str_del)

        try:
            # Fix for index out of bounds exception while parsing
            # subfolders _not_ included by the split
            if len(spl_str) > 1:
                file_url += ((spl_str[1])
                             .replace('\\', '/'))
            else:
                broken_splt = filename.split(self.source_input)[1]
                other_dirs.add(broken_splt)
        except Exception as exc:  # Generic exception thrown directly to user
            self.update_scroll("[!!] Error parsing: " +
                               "%s\n\tException: %s"
                               % (filename, str(exc)))
        if self._ext_test(ext):
            if file_url != self.config.get("URL"):
                file_set.add(file_url)
        else:
            other_dirs.discard(broken_splt)
        return file_set, other_dirs

    def _ext_test(self, ext):
        """Litmus test for extension whitelist"""
        val = False
        if len(self.config.get("Extension Whitelist")) > 0:
            val = (len(ext) > 0 and
                   (ext.strip().upper()
                    in self.config.get("Extension Whitelist")))
        elif "*" in self.config.get("Extension Whitelist"):
            val = True
        return val

    def _update(self):
        """Updates internal data"""
        self.config["Input Directory"] = self.source_input
        self.config["String Delimiter"] = self.delim.getText()

        white_list_text = self.ext_white_list.getText()
        self.config["Extension Whitelist"] = white_list_text.upper().split(',')
        file_url = self.url.getText()
        if not file_url.endswith('/') and file_url != "":
            file_url += '/'

        self.config["URL"] = file_url
        # self.config["Cookies"] = self.cookies.getText()
        # self.config["Headers"] = self.headers.getText()
        del self.url_reqs[:]
        self.curr_conf.setText(self.source_input)

    # Window sizing functions
    def resize(self, event):
        """Resizes the window to better fit Burp"""
        if self.parent_window is not None:
            par_size = self.parent_window.getSize()
            par_size.setSize(par_size.getWidth() * .99,
                             par_size.getHeight() * .9)
            self.tab.setPreferredSize(par_size)
            self.parent_window.validate()
            self.parent_window.switch_focus()

    def p_close(self, event):
        """
        Handles the window close event.
        """
        self.window.setVisible(False)
        self.window.dispose()

    def p_build_ui(self, event):
        """
        Adds a list of checkboxes, one for each loaded plugin
        to the Selct plugins window
        """
        if not self.loaded_p_list:
            self.update_scroll("[!!] No plugins loaded!")
            return

        scroll_pane = JScrollPane()
        scroll_pane.setPreferredSize(Dimension(200, 250))
        check_frame = JPanel(GridBagLayout())
        constraints = GridBagConstraints()
        constraints.fill = GridBagConstraints.HORIZONTAL
        constraints.gridy = 0
        constraints.anchor = GridBagConstraints.FIRST_LINE_START

        for plug in self.loaded_p_list:
            check_frame.add(JCheckBox(plug.get_name(), plug.enabled,
                                      actionPerformed=self.update_box),
                            constraints)
            constraints.gridy += 1

        vport = JViewport()
        vport.setView(check_frame)
        scroll_pane.setViewport(vport)
        self.window.contentPane.add(scroll_pane)
        self.window.pack()
        self.window.setVisible(True)

    def update_box(self, event):
        """
        Handles the check/uncheck event for the plugin's box.
        """
        for plug in self.loaded_p_list:
            if plug.get_name() == event.getActionCommand():
                plug.enabled = not plug.enabled
                if plug.enabled:
                    self.update_scroll("[^] Enabled: %s" %
                                       event.getActionCommand())
                else:
                    self.update_scroll("[^] Disabled: %s" %
                                       event.getActionCommand())

    # ITab required functions
    @staticmethod
    def getTabCaption():
        """Returns the name of the Burp Suite Tab"""
        return "SpyDir"

    def getUiComponent(self):
        """Returns the UI component for the Burp Suite tab"""
        return self.tab
Esempio n. 12
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]
Esempio n. 13
0
class WorkHelper(JFrame):

    def __init__(self):
        super(WorkHelper, self).__init__()

        self.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard()
        #self.initUI()

    #def initUI(self):

        #panel = JPanel()
        #self.getContentPane().add(panel)
        
#############################################################
# Layout
        layout = GroupLayout(self.getContentPane())
        self.getContentPane().setLayout(layout)
        layout.setAutoCreateGaps(True)
        layout.setAutoCreateContainerGaps(True)
#############################################################

#############################################################
# Scroll Area Input + Output
        Larea1 = JLabel("InputArea:")
        Larea2 = JLabel("OutputArea:")
        
        Sarea1 = JScrollPane()
        Sarea2 = JScrollPane()
        
        self.area1 = JTextArea()
        self.area1.setToolTipText("Input Area")
        self.area1.setEditable(True)
        self.area1.setBorder(BorderFactory.createLineBorder(Color.gray))
        
        Sarea1.setPreferredSize(Dimension(300,100))
        Sarea1.getViewport().setView((self.area1))
        
        self.area2 = JTextArea()
        self.area2.setToolTipText("Output Area")
        self.area2.setEditable(False)
        self.area2.setBorder(BorderFactory.createLineBorder(Color.gray))
        
        Sarea2.setPreferredSize(Dimension(300,100))
        Sarea2.getViewport().setView((self.area2))
#############################################################

#############################################################
# Buttons

        self.cCurly = JCheckBox("Curly");
        self.cCurly.setToolTipText("When 'Checked' Curly Brackets will surround the Categories")
        self.cCurly.setSelected(1)
        

        self.cCtClipB = JCheckBox("Auto-Copy");
        self.cCtClipB.setToolTipText("When 'Checked' after the Categories are created they will added to the clipboard")
        self.cCtClipB.setSelected(1)

        self.cSemiC = JCheckBox("SemiColumn");
        self.cSemiC.setToolTipText("When 'Checked' after the Categories are created at the end will be a semicolomn")
        self.cSemiC.setSelected(1)        
        
        bRemoveNBSP_L = JButton("Clean LText", actionPerformed=self.bRemoveNBSP_L)
        bRemoveNBSP_L.setToolTipText("Removes Spaces, Tabs from the start of every text line from the input Area")
        bRemoveNBSP_R = JButton("Clean RText", actionPerformed=self.bRemoveNBSP_R)
        bRemoveNBSP_R.setToolTipText("Removes Spaces, Tabs from the end of every text line from the input Area")
        bCopyToInput = JButton("Copy to Input", actionPerformed=self.bCopyToInput)
        bCopyToInput.setToolTipText("Copy the text from the Output Area to the Input Area for further Operations")
        
        bClear = JButton("Clear", actionPerformed=self.bClear)
        bClear.setToolTipText("Clears the text form both Input and Output text Areas")
        
        self.iStart = JTextField(maximumSize=Dimension(40,25))
        self.iStart.setToolTipText("The Start Index for the Making of the Categories")
        
        self.RThis = JTextField()
        self.RThis = JTextField(maximumSize=Dimension(120,25))
        self.RThis.setToolTipText("Text to be replaced or The Starting C_Index")
        
        self.RThat = JTextField()
        self.RThat = JTextField(maximumSize=Dimension(120,25))
        self.RThat.setToolTipText("Text to be placed or The Finish C_Index")
        
        
        bSandReplace = JButton("Replace Text", actionPerformed=self.bSandReplace)
        bSandReplace.setToolTipText("Replace the text from This with Thext from That in the Text from the Input Area and displays it in the Output Area")
        
        bcCat = JButton("CreatCateg", actionPerformed=self.bcCat)
        bcCat.setToolTipText("Create a categorical form starting C_Index to finish C_Index; Use the above text boxes to define the indexes")
        
        
        bC_S = JButton("Create _Series", actionPerformed=self.bC_S)
        bC_S.setToolTipText("Create a series form starting C_Index to finish C_Index; Use the above text boxes to define the indexes; It will create a series for every row in the Input Area")

        
        
        bM_Categories = JButton("Categories", actionPerformed=self.mCategories)
        bM_Categories.setToolTipText("Make Categories using the lines from the Input Area")
        #bM_Categories = JButton(maximumSize=Dimension(40,25))
        # de incercat daca merge cu ; sa grupezi in [dsa] elementele
#############################################################


#############################################################
# Aplication Layout 2 groups one Horizontal and one Vertical
        layout.setHorizontalGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup()
                .addComponent(Larea1)
                .addComponent(Sarea1)

                .addComponent(Sarea2)
                .addComponent(bCopyToInput)
                .addComponent(Larea2))
            .addGroup(layout.createParallelGroup()
            .addGroup(layout.createSequentialGroup()
                .addComponent(bM_Categories)
                .addComponent(self.iStart))
            .addGroup(layout.createSequentialGroup()
                .addComponent(self.cCurly)
                .addComponent(self.cSemiC)
                .addComponent(self.cCtClipB))
            .addGroup(layout.createSequentialGroup()
                .addComponent(bRemoveNBSP_L)
                .addComponent(bRemoveNBSP_R))
            .addGroup(layout.createSequentialGroup()
                .addComponent(self.RThis)
                .addComponent(self.RThat))
            .addGroup(layout.createSequentialGroup()
                .addComponent(bSandReplace)
                .addComponent(bcCat))
            .addGroup(layout.createSequentialGroup()
                .addComponent(bC_S))
                
                .addComponent(bClear))
            
        )

        layout.setVerticalGroup(layout.createSequentialGroup()
            .addComponent(Larea1)
            
            .addGroup(layout.createParallelGroup()
                .addComponent(Sarea1)
                
                .addGroup(layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup()
                        .addComponent(bM_Categories)
                        .addComponent(self.iStart))
                    .addGroup(layout.createParallelGroup()
                        .addComponent(self.cCurly)
                        .addComponent(self.cSemiC)
                        .addComponent(self.cCtClipB))
                    .addGroup(layout.createParallelGroup()
                        .addComponent(bRemoveNBSP_L)
                        .addComponent(bRemoveNBSP_R))
                    .addGroup(layout.createParallelGroup()
                        .addComponent(self.RThis)
                        .addComponent(self.RThat))
                    .addGroup(layout.createParallelGroup()   
                        .addComponent(bSandReplace)
                        .addComponent(bcCat))
                    .addGroup(layout.createParallelGroup()
                        .addComponent(bC_S))
                        
                        
                        )
                    )
                
            .addGroup(layout.createParallelGroup()
                .addComponent(bCopyToInput)
                .addComponent(bClear))
            .addComponent(Larea2)
            .addGroup(layout.createParallelGroup()
                .addComponent(Sarea2))
        )
        
        #layout.linkSize(SwingConstants.HORIZONTAL, [ok, bCopyToInput, close, bM_Categories])
        layout.linkSize(SwingConstants.HORIZONTAL, [self.RThis,self.RThat,bRemoveNBSP_L,bRemoveNBSP_R,bCopyToInput,bM_Categories,bSandReplace,bcCat,bC_S])
        
        #layout.linkSize(SwingConstants.HORIZONTAL, [self.cCurly,bM_Categories])
#############################################################

#############################################################
# Aplication Settings
        self.pack()
        #self.setPreferredSize(Dimension(1000, 1000))
        self.setTitle("Workhelper")
        self.setSize(800, 500)
        self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
        self.setLocationRelativeTo(None)
        self.setVisible(True)
#############################################################
        
#############################################################
# WorkHelper class methods:
    def onQuit(self, e):
        "@sig public void setExpression(java.lang.String e)"
        System.exit(0)


# def addToClipBoard(self, text):
# "@sig public void setExpression(java.lang.String text)"
# command = 'echo ' + text.strip() + '| clip'
# os.system(command)
# brute method for pasting into clipboard on windows



        
    def mCategories(self, e):
        "@sig public void setExpression(java.lang.String e)"
        """
Takes every line of text form the Input Area and by using a
string composotion it creates the output in the SPSS dimension
categories format.
"""
        try:
            StartIndex = int(self.iStart.getText())
        except ValueError:
            StartIndex=1




        text=self.area1.getText().rstrip()
        
        
        counter=StartIndex
        lastindex=0
        textO=""
        
        for i in range(0,len(text)):
                if text[i]=='\n':
                        textO=textO+("_"+str(counter)+' "'+text[lastindex:i]+'",\n')
                        lastindex=i+1
                        counter=counter+1

        if len(text[lastindex:len(text)])>0:
                textO=textO+("_"+str(counter)+' "'+text[lastindex:len(text)]+'"')


        if len(textO)>0:
            if self.cCurly.isSelected():
                textO = "{\n"+ textO + "\n}"
                if self.cSemiC.isSelected():
                    textO = textO + ";"
            self.copyToClipboard(textO)    
            self.area2.setText(textO)
    
    def copyToClipboard(self, text):
            if self.cCtClipB.isSelected():
                stringSelection = StringSelection(text)
                self.clipboard.setContents(stringSelection, None)
            
        
        
    def bCopyToInput(self, e):
        "@sig public void setExpression(java.lang.String e)"
        """Copy the Text from the Output Area to the input Area for further operations"""
        
        self.area1.setText(self.area2.getText())
    
    def bRemoveNBSP_L(self, e):
        "@sig public void setExpression(java.lang.String e)"
        text=self.area1.getText().rstrip()
        textO=""
        lastindex=0
        
        for i in range(0,len(text)):
            if text[i] == '\n':
                textO = textO+text[lastindex:i].lstrip()+"\n"
                lastindex=i+1
                #print(text[0:i].lstrip()+'\n')
        if len(text[lastindex:len(text)])>0:
                textO=textO+text[lastindex:len(text)].lstrip()
        self.area2.setText(textO)
    
    def bRemoveNBSP_R(self, e):
        "@sig public void setExpression(java.lang.String e)"
        text=self.area1.getText().rstrip()
        textO=""
        lastindex=0
        
        for i in range(0,len(text)):
            if text[i] == '\n':
                textO = textO+text[lastindex:i].rstrip()+"\n"
                lastindex=i+1
                #print(text[0:i].lstrip()+'\n')
        if len(text[lastindex:len(text)])>0:
                textO=textO+text[lastindex:len(text)].rstrip()
        self.area2.setText(textO)
        
    def bClear(self, e):
        "@sig public void setExpression(java.lang.String e)"
        self.area1.setText("")
        self.area2.setText("")
    
    def bcCat(self, e):
        "@sig public void setExpression(java.lang.String e)"
        try:
            StartIndex = int(self.RThis.getText())
        except ValueError:
            StartIndex=1
        
        try:
            FinishIndex = int(self.RThat.getText())
        except ValueError:
            FinishIndex=1
        cCats=""
        for i in range(StartIndex,FinishIndex+1):
            if i<>FinishIndex:
                cCats=cCats+"_"+str(i)+","
            else:
                cCats=cCats+"_"+str(i)
            
        if StartIndex<FinishIndex:
            cCats="{"+cCats+"}"
            self.copyToClipboard(cCats)
            self.area2.setText(cCats)
        
    def bSandReplace(self, e):
        self.area2.setText(self.area1.getText().replace(self.RThis.getText(),self.RThat.getText()))
        
    def bC_S(self, e):
        "@sig public void setExpression(java.lang.String e)"
        try:
            StartIndex = int(self.RThis.getText())
        except ValueError:
            StartIndex=1
        
        try:
            FinishIndex = int(self.RThat.getText())
        except ValueError:
            FinishIndex=1
        
        if StartIndex<FinishIndex:
            text=self.area1.getText().rstrip()
            lastindex=0
            textO=""
            
            for i in range(0,len(text)):
                    if text[i]=='\n':
                        counter=StartIndex
                        for j in range(StartIndex,FinishIndex+1):
                            textO=textO+(text[lastindex:i]+"_"+str(counter)+" ")
                            counter=counter+1
                        lastindex=i+1
                        textO=textO+'\n'

            #if len(text[lastindex:len(text)])>0:
            #        textO=textO+("_"+str(counter)+' "'+text[lastindex:len(text)]+'"')

            if lastindex==0 and len(text)>0:
                counter=StartIndex
                for j in range(StartIndex,FinishIndex+1):
                    textO=textO+(text[lastindex:i]+"_"+str(counter)+" ")
                    counter=counter+1
            
            if len(textO)>0:
                self.copyToClipboard(textO)    
                self.area2.setText(textO)
Esempio n. 14
0
class WorkHelper(JFrame):

    def __init__(self):
        super(WorkHelper, self).__init__()
        self.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard()

#############################################################
# Layout:
        layout = GroupLayout(self.getContentPane())
        self.getContentPane().setLayout(layout)
        layout.setAutoCreateGaps(True)
        layout.setAutoCreateContainerGaps(True)
#############################################################

#############################################################
# Frame Area:
        Larea1 = JLabel("InputArea:")

        Sarea1 = JScrollPane()
        self.area1 = JTextArea()
        self.area1.setToolTipText("Input Area")
        self.area1.setEditable(True)
        self.area1.setBorder(BorderFactory.createLineBorder(Color.gray))
        Sarea1.setPreferredSize(Dimension(300,100))
        Sarea1.getViewport().setView((self.area1))

        bClear = JButton("Clear", actionPerformed=self.bClear)
        bClear.setToolTipText("Clears the text form both Input and Output text Areas")

        bCopyToInput = JButton("Copy to Input", actionPerformed=self.bCopyToInput)
        bCopyToInput.setToolTipText("Copy the text from the Output Area to the Input Area for further Operations")
        
        self.cCtClipB = JCheckBox("Auto-Copy");
        self.cCtClipB.setToolTipText("When 'Checked' after the Categories are created they will added to the clipboard")
        self.cCtClipB.setSelected(1)
        
        Larea2 = JLabel("OutputArea:")
        
        Sarea2 = JScrollPane()
        self.area2 = JTextArea()
        self.area2.setToolTipText("Output Area")
        self.area2.setEditable(False)
        self.area2.setBorder(BorderFactory.createLineBorder(Color.gray))
        Sarea2.setPreferredSize(Dimension(300,100))
        Sarea2.getViewport().setView((self.area2))

#############################################################
# Tabbed Area:
        tabPane = JTabbedPane(JTabbedPane.TOP)
        self.getContentPane().add(tabPane)
        #####################################################
        # Text Edit pane
        panel_TEdit = JPanel()
        layout2 = GroupLayout(panel_TEdit)
        layout2.setAutoCreateGaps(True)
        layout2.setAutoCreateContainerGaps(True)
        panel_TEdit.setLayout(layout2)
        
        bRemoveNBSP_L = JButton("Clean LText", actionPerformed=self.bRemoveNBSP_L)
        bRemoveNBSP_L.setToolTipText("Removes Spaces, Tabs from the start of every text line from the input Area")
        bRemoveNBSP_R = JButton("Clean RText", actionPerformed=self.bRemoveNBSP_R)
        bRemoveNBSP_R.setToolTipText("Removes Spaces, Tabs from the end of every text line from the input Area")
    
        
        self.ReplaceThis = JTextField()
        self.ReplaceThis = JTextField(maximumSize=Dimension(120,25))
        self.ReplaceThis.setToolTipText("Text to be replaced")

        self.ReplaceThat = JTextField()
        self.ReplaceThat = JTextField(maximumSize=Dimension(120,25))
        self.ReplaceThat.setToolTipText("Text to be placed")

        bSandReplace = JButton("Replace Text", actionPerformed=self.bSandReplace)
        bSandReplace.setToolTipText("Replace the text from This with Text from That in the Text from the Input Area and displays it in the Output Area")

        bRemNumbers = JButton("Rem Numbers", actionPerformed=self.RemNumbers)
        bRemNumbers.setToolTipText("Removes numbers from the start of every line")
        #####################################################
        # Dimension pane
        panel_Dimensions = JPanel()
        layout3 = GroupLayout(panel_Dimensions)
        layout3.setAutoCreateGaps(True)
        layout3.setAutoCreateContainerGaps(True)
        panel_Dimensions.setLayout(layout3)
        
        
        self.cCurly = JCheckBox("Curly");
        self.cCurly.setToolTipText("When 'Checked' Curly Brackets will surround the Categories")
        self.cCurly.setSelected(1)

        self.cSemiC = JCheckBox("SemiColumn");
        self.cSemiC.setToolTipText("When 'Checked' after the Categories are created at the end will be a semicolomn")
        self.cSemiC.setSelected(1)

        self.iStart = JTextField(maximumSize=Dimension(40,25))
        self.iStart.setToolTipText("The Start Index for the Making of the Categories")

        self.RThis = JTextField()
        self.RThis = JTextField(maximumSize=Dimension(120,25))
        self.RThis.setToolTipText("The Starting Index used in creating the Categorical")

        self.RThat = JTextField()
        self.RThat = JTextField(maximumSize=Dimension(120,25))
        self.RThat.setToolTipText("The Finish Index used in creating the Categorical")
        
        optioncCategories = JLabel("Options:")
        bcCat = JButton("CreatCateg", actionPerformed=self.bcCat)
        bcCat.setToolTipText("Create a categorical form starting C_Index to finish C_Index; Use the text boxes to define the indexes")

        bM_Categories = JButton("Categories", actionPerformed=self.mCategories)
        bM_Categories.setToolTipText("Make Categories using the lines from the Input Area. Use it to define Categorical questions.")
        #####################################################
        # ConfirmIt pane
        panel_ConfirmIt = JPanel()
        layout4 = GroupLayout(panel_ConfirmIt)
        layout4.setAutoCreateGaps(True)
        layout4.setAutoCreateContainerGaps(True)
        panel_ConfirmIt.setLayout(layout4)
        
        self.PID = JTextField()
        self.PID = JTextField(maximumSize=Dimension(120,25))
        self.PID.setToolTipText("The PID number used for creating links with PID and ids from every line of the Input Area")
        
        bClinks = JButton("Create Links", actionPerformed=self.bClinks)
        bClinks.setToolTipText("Create links for a project using PID and ID, ID`s are read from every line of the Input Area")
        
        bClinksNA = JButton("Create Links NA ", actionPerformed=self.bClinksNA)
        bClinksNA.setToolTipText("Create links for a project using PID and ID`s from the standard sample test for US")
        
        bClinksCA = JButton("Create Links CA", actionPerformed=self.bClinksCA)
        bClinksCA.setToolTipText("Create links for a project using PID and ID`s from the standard sample test for CA")
        
        self.Width = JTextField()
        self.Width = JTextField(maximumSize=Dimension(120,25))
        self.Width.setToolTipText("The Width used in creating the DIV html tag, note the dimension used is in px")
        
        baddDIVt = JButton("Add DIV tag", actionPerformed=self.baddDIVt)
        baddDIVt.setToolTipText("Create a DIV tag for every line in the Input Area")
        #####################################################
        # Statistics pane
        panel_Statistics = JPanel()
        layout5 = GroupLayout(panel_Statistics)
        layout5.setAutoCreateGaps(True)
        layout5.setAutoCreateContainerGaps(True)
        panel_Statistics.setLayout(layout5)         
        
        #####################################################
        # TimeTraking pane
        panel_TimeTraking = JPanel()
        layout6 = GroupLayout(panel_TimeTraking)
        layout6.setAutoCreateGaps(True)
        layout6.setAutoCreateContainerGaps(True)
        panel_TimeTraking.setLayout(layout6)     
        
        #####################################################
        # Tabbed Area Tabs
        tabPane.addTab("Text Edit", panel_TEdit)
        tabPane.addTab("Dimensions", panel_Dimensions)
        tabPane.addTab("ConfirmIt", panel_ConfirmIt)
        tabPane.addTab("Statistics", panel_Statistics)
        tabPane.addTab("TimeTraking", panel_TimeTraking)
        
        
#############################################################




#############################################################
# Aplication Layouts: 2 groups one Horizontal and one Vertical
        
        #############################################################
        # Frame Layout: 2 groups one Horizontal and one Vertical
        layout.setHorizontalGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup()
                .addComponent(Larea1)
                .addComponent(Sarea1)
                .addComponent(Sarea2)
                .addGroup(layout.createSequentialGroup()
                          .addComponent(bCopyToInput)
                          .addComponent(bClear)
                          .addComponent(self.cCtClipB))
                .addComponent(Larea2))
            .addGroup(layout.createParallelGroup()
                .addComponent(tabPane))
                        )

        layout.setVerticalGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup()
                      .addGroup(layout.createSequentialGroup()
                          .addComponent(Larea1)
                          .addComponent(Sarea1)
                          .addGroup(layout.createParallelGroup()
                                    .addComponent(bCopyToInput)
                                    .addComponent(bClear)
                                    .addComponent(self.cCtClipB)    )
                          .addComponent(Larea2)
                          .addComponent(Sarea2))
                      .addGroup(layout.createSequentialGroup()
                          .addComponent(tabPane))
                          )
                        )

        #############################################################
        # TEdit Layout: 2 groups one Horizontal and one Vertical
        layout2.setHorizontalGroup(layout2.createSequentialGroup()
            .addGroup(layout2.createParallelGroup()
                .addGroup(layout2.createSequentialGroup()
                    .addComponent(bRemNumbers)
                    .addComponent(bRemoveNBSP_L)
                    .addComponent(bRemoveNBSP_R))
                    .addGroup(layout2.createSequentialGroup()
                    .addComponent(bSandReplace)
                    .addComponent(self.ReplaceThis)
                    .addComponent(self.ReplaceThat))  
                      
                      
                      
                                   ))
        
        layout2.setVerticalGroup(layout2.createSequentialGroup()
            .addGroup(layout2.createParallelGroup()
                .addComponent(bRemNumbers)
                .addComponent(bRemoveNBSP_L)
                .addComponent(bRemoveNBSP_R))
                                 
                .addGroup(layout2.createParallelGroup()
                    .addComponent(bSandReplace)
                    .addComponent(self.ReplaceThis)
                    .addComponent(self.ReplaceThat))  
                                 )
            
            
        #############################################################
        # Dimensions Layout: 2 groups one Horizontal and one Vertical
        layout3.setHorizontalGroup(layout3.createSequentialGroup()
        
         .addGroup(layout3.createParallelGroup()
            .addGroup(layout3.createSequentialGroup()
                .addComponent(bM_Categories)
                .addComponent(self.iStart))
            .addGroup(layout3.createSequentialGroup()
                .addComponent(optioncCategories)
                .addComponent(self.cCurly)
                .addComponent(self.cSemiC)
                )
           
            .addGroup(layout3.createSequentialGroup()
                .addComponent(bcCat)
                .addComponent(self.RThis)
                .addComponent(self.RThat))
            .addGroup(layout3.createSequentialGroup()
                
                )

                )
        )
        
        layout3.setVerticalGroup(layout3.createSequentialGroup()
            .addGroup(layout3.createSequentialGroup()
                    .addGroup(layout3.createParallelGroup()
                        .addComponent(bM_Categories)
                        .addComponent(self.iStart))
                    
                    .addGroup(layout3.createParallelGroup()
                        .addComponent(bcCat)
                        .addComponent(self.RThis)
                        .addComponent(self.RThat))
                    .addGroup(layout3.createParallelGroup()
                        
                    .addGroup(layout3.createParallelGroup()
                        .addComponent(optioncCategories)
                        .addComponent(self.cCurly)
                        .addComponent(self.cSemiC)
                        )
                   
                                )
                        )
            
            )
        #############################################################
        # ConfimIT Layout: 2 groups one Horizontal and one Vertical
        layout4.setHorizontalGroup(layout4.createSequentialGroup()
        
         .addGroup(layout4.createParallelGroup()
            .addGroup(layout4.createSequentialGroup()
                .addComponent(bClinks)
                .addComponent(self.PID)
                )
            .addGroup(layout4.createSequentialGroup()
                .addComponent(bClinksNA)
                .addComponent(bClinksCA)
                )
            .addGroup(layout4.createSequentialGroup()
                .addComponent(baddDIVt)
                .addComponent(self.Width)
                
                )
                
                ))
        
        
        layout4.setVerticalGroup(layout4.createSequentialGroup()
            .addGroup(layout4.createSequentialGroup()
                    .addGroup(layout4.createParallelGroup()
                        .addComponent(bClinks)
                        .addComponent(self.PID))
                    .addGroup(layout4.createParallelGroup()
                        .addComponent(bClinksNA)
                        .addComponent(bClinksCA)
                        )
                    
                    .addGroup(layout4.createParallelGroup()
                        .addComponent(baddDIVt)
                        .addComponent(self.Width)
                        )
                    
                        
                        ))
        
        
        #layout2.linkSize(SwingConstants.HORIZONTAL, [self.cCurly,bM_Categories])
        #layout.linkSize(SwingConstants.HORIZONTAL, [ok, bCopyToInput, close, bM_Categories])
        #layout3.linkSize(SwingConstants.HORIZONTAL, [self.RThis,self.RThat,bRemoveNBSP_L,bRemoveNBSP_R,bM_Categories,bSandReplace,bcCat])

        
#############################################################

#############################################################
# Aplication Settings
        self.pack()
        #self.setPreferredSize(Dimension(1000, 1000))
        self.setTitle("Workhelper")
        self.setSize(800, 500)
        self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
        self.setLocationRelativeTo(None)
        self.setVisible(True)
#############################################################

#############################################################
# WorkHelper class methods:
    def onQuit(self, e):
        "@sig public void setExpression(java.lang.String e)"
        os.system.exit(0)


# def addToClipBoard(self, text):
# "@sig public void setExpression(java.lang.String text)"
# command = 'echo ' + text.strip() + '| clip'
# os.system(command)
# brute method for pasting into clipboard on windows




    def mCategories(self, e):
        "@sig public void setExpression(java.lang.String e)"
        """
        Takes every line of text form the Input Area and by using a
        string composition it creates the output in the SPSS dimension
        categories format.
        """
        try:
            StartIndex = int(self.iStart.getText())
        except ValueError:
            StartIndex=1




        text=self.area1.getText().rstrip()


        counter=StartIndex
        lastindex=0
        textO=""

        for i in range(0,len(text)):
                if text[i]=='\n':
                        textO=textO+("_"+str(counter)+' "'+text[lastindex:i]+'",\n')
                        lastindex=i+1
                        counter=counter+1

        if len(text[lastindex:len(text)])>0:
                textO=textO+("_"+str(counter)+' "'+text[lastindex:len(text)]+'"')


        if len(textO)>0:
            if self.cCurly.isSelected():
                textO = "{\n"+ textO + "\n}"
                if self.cSemiC.isSelected():
                    textO = textO + ";"
            self.copyToClipboard(textO)
            self.area2.setText(textO)

    def copyToClipboard(self, text):
            if self.cCtClipB.isSelected():
                stringSelection = StringSelection(text)
                self.clipboard.setContents(stringSelection, None)



    def bCopyToInput(self, e):
        "@sig public void setExpression(java.lang.String e)"
        """Copy the Text from the Output Area to the input Area for further operations"""

        self.area1.setText(self.area2.getText())

    def bRemoveNBSP_L(self, e):
        "@sig public void setExpression(java.lang.String e)"
        text=self.area1.getText().rstrip()
        textO=""
        lastindex=0

        for i in range(0,len(text)):
            if text[i] == '\n':
                textO = textO+text[lastindex:i].lstrip()+"\n"
                lastindex=i+1
                #print(text[0:i].lstrip()+'\n')
        if len(text[lastindex:len(text)])>0:
                textO=textO+text[lastindex:len(text)].lstrip()
        self.area2.setText(textO)

    def bRemoveNBSP_R(self, e):
        "@sig public void setExpression(java.lang.String e)"
        text=self.area1.getText().rstrip()
        textO=""
        lastindex=0

        for i in range(0,len(text)):
            if text[i] == '\n':
                textO = textO+text[lastindex:i].rstrip()+"\n"
                lastindex=i+1
                #print(text[0:i].lstrip()+'\n')
        if len(text[lastindex:len(text)])>0:
                textO=textO+text[lastindex:len(text)].rstrip()
        self.area2.setText(textO)

    def bClear(self, e):
        "@sig public void setExpression(java.lang.String e)"
        self.area1.setText("")
        self.area2.setText("")

    def bcCat(self, e):
        "@sig public void setExpression(java.lang.String e)"
        try:
            StartIndex = int(self.RThis.getText())
        except ValueError:
            StartIndex=1

        try:
            FinishIndex = int(self.RThat.getText())
        except ValueError:
            FinishIndex=1
        cCats=""
        for i in range(StartIndex,FinishIndex+1):
            if i<>FinishIndex:
                cCats=cCats+"_"+str(i)+","
            else:
                cCats=cCats+"_"+str(i)

        if StartIndex<FinishIndex:
            cCats="{"+cCats+"}"
            self.copyToClipboard(cCats)
            self.area2.setText(cCats)

    def bSandReplace(self, e):
        self.area2.setText(self.area1.getText().replace(self.ReplaceThis.getText(),self.ReplaceThat.getText()))
        self.copyToClipboard(self.area2.getText())

    #############################################################
    # Confirmit
    def bClinks(self, e):
    
    
        text=self.area1.getText().rstrip()

        lastindex=0
        textO=""

        for i in range(0,len(text)):
                if text[i]=='\n':
                    textO=textO+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+text[lastindex:i]+'\n'
                    lastindex=i+1

        if len(text[lastindex:len(text)])>0:
                textO=textO+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+text[lastindex:len(text)]

        self.copyToClipboard(textO)
        self.area2.setText(textO)
        
    def bClinksNA(self, e):
        
        
        output=""
        
        for i in range (1,201):
        
            if i<10:
                output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'US9900'+str(i)+'\n'
            else:
                if i<100:
                    output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'US990'+str(i)+'\n'
                else:
                    if i==200:
                        output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'US99'+str(i)
                    else: 
                        output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'US99'+str(i)+'\n'
        
        
        self.area2.setText(output)
        self.copyToClipboard(self.area2.getText())
        
    def bClinksCA(self, e):
        output=""
        
        for i in range (1,201):
        
            if i<10:
                output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'CA9900'+str(i)+'\n'
            else:
                if i<100:
                    output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'CA990'+str(i)+'\n'
                else:
                    if i==200:
                        output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'CA99'+str(i)
                    else: 
                        output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'CA99'+str(i)+'\n'
        
        
        self.area2.setText(output)
        self.copyToClipboard(self.area2.getText())
        
    def baddDIVt(self, e):
        
        try:
            Width = int(self.Width.getText())
        except ValueError:
            Width=1
            
        text=self.area1.getText().rstrip()

        lastindex=0
        textO=""

        for i in range(0,len(text)):
            if text[i]=='\n':
                textO=textO+'<div style="width:'+str(Width)+'px">'+text[lastindex:i]+'</div>'+'\n'
                lastindex=i+1

        if len(text[lastindex:len(text)])>0:
            textO=textO+'<div style="width:'+str(Width)+'px">'+text[lastindex:len(text)]+'</div>'
            

        self.copyToClipboard(textO)
        self.area2.setText(textO)
        
    def RemNumbers(self, e):
        text=self.area1.getText().rstrip()

        lastindex=0
        textO=""
        
        
        for i in range(0,len(text)):
            if text[i]=='\n':
                textO=textO+text[lastindex:i].lstrip('1234567890')+'\n'
                lastindex=i+1
        if len(text[lastindex:len(text)])>0:
            textO=textO+text[lastindex:len(text)].lstrip('1234567890')
            

        self.copyToClipboard(textO)
        self.area2.setText(textO)
Esempio n. 15
0
class BurpExtender(IBurpExtender, ITab, IMessageEditorController, AbstractTableModel, IContextMenuFactory):

    def registerExtenderCallbacks(self, callbacks):
        # keep a reference to our callbacks object
        self._callbacks = callbacks
        # obtain an extension helpers object
        self._helpers = callbacks.getHelpers()
        
        # set our extension name
        callbacks.setExtensionName("PT Vulnerabilities Manager")
        
        self.config = SafeConfigParser()
        self.createSection('projects')
        self.createSection('general')
        self.config.read('config.ini')
        self.chooser = JFileChooser()
        # create the log and a lock on which to synchronize when adding log entries
        self._log = ArrayList()
        self._lock = Lock()
        
        self.logTable = Table(self)
        self.logTable.getColumnModel().getColumn(0).setMaxWidth(35)
        self.logTable.getColumnModel().getColumn(1).setMinWidth(100)

        self._requestViewer = self._callbacks.createMessageEditor(self, False)
        self._responseViewer = self._callbacks.createMessageEditor(self, False)

        self.initVulnerabilityTab()
        self.initProjSettingsTab()
        self.initTabs()
        self.initCallbacks()

        if self.projPath.getText() != None:
            self.loadVulnerabilities(self.projPath.getText())

        print "Thank you for installing PT Vulnerabilities Manager v1.0 extension"
        print "by Barak Tawily\n\n\n"
        print "Disclaimer:\nThis extension might create folders and files in your hardisk which might be declared as sensitive information, make sure you are creating projects under encrypted partition"
        return

    def initVulnerabilityTab(self):
        #
        ##  init vulnerability tab
        #

        nameLabel = JLabel("Vulnerability Name:")
        nameLabel.setBounds(10, 10, 140, 30)

        self.addButton = JButton("Add",actionPerformed=self.addVuln)
        self.addButton.setBounds(10, 500, 100, 30) 

        rmVulnButton = JButton("Remove",actionPerformed=self.rmVuln)
        rmVulnButton.setBounds(465, 500, 100, 30)

        mitigationLabel = JLabel("Mitigation:")
        mitigationLabel.setBounds(10, 290, 150, 30)
        
        addSSBtn = JButton("Add SS",actionPerformed=self.addSS)
        addSSBtn.setBounds(750, 40, 110, 30) 

        deleteSSBtn = JButton("Remove SS",actionPerformed=self.removeSS)
        deleteSSBtn.setBounds(750, 75, 110, 30) 

        piclistLabel = JLabel("Images list:")
        piclistLabel.setBounds(580, 10, 140, 30)

        self.screenshotsList = DefaultListModel()
        self.ssList = JList(self.screenshotsList)
        self.ssList.setBounds(580, 40, 150, 250)
        self.ssList.addListSelectionListener(ssChangedHandler(self))
        self.ssList.setBorder(BorderFactory.createLineBorder(Color.GRAY))

        previewPicLabel = JLabel("Selected image preview: (click to open in image viewer)")
        previewPicLabel.setBounds(580, 290, 500, 30)


        copyImgMenu = JMenuItem("Copy")
        copyImgMenu.addActionListener(copyImg(self))

        self.imgMenu = JPopupMenu("Popup")
        self.imgMenu.add(copyImgMenu)

        self.firstPic = JLabel()
        self.firstPic.setBorder(BorderFactory.createLineBorder(Color.GRAY))
        self.firstPic.setBounds(580, 320, 550, 400)
        self.firstPic.addMouseListener(imageClicked(self))

        self.vulnName = JTextField("")
        self.vulnName.getDocument().addDocumentListener(vulnTextChanged(self))
        self.vulnName.setBounds(140, 10, 422, 30)

        sevirities = ["Unclassified", "Critical","High","Medium","Low"]
        self.threatLevel = JComboBox(sevirities);
        self.threatLevel.setBounds(140, 45, 140, 30)

        colors = ["Color:", "Green", "Red"]
        self.colorCombo = JComboBox(colors);
        self.colorCombo.setBounds(465, 45, 100, 30)
        self.colorCombo

        severityLabel = JLabel("Threat Level:")
        severityLabel.setBounds(10, 45, 100, 30)

        descriptionLabel = JLabel("Description:")
        descriptionLabel.setBounds(10, 80, 100, 30)

        self.descriptionString = JTextArea("", 5, 30)
        self.descriptionString.setWrapStyleWord(True);
        self.descriptionString.setLineWrap(True)
        self.descriptionString.setBounds(10, 110, 555, 175)
        descriptionStringScroll = JScrollPane(self.descriptionString)
        descriptionStringScroll.setBounds(10, 110, 555, 175)
        descriptionStringScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED)


        self.mitigationStr = JTextArea("", 5, 30)
        self.mitigationStr.setWrapStyleWord(True);
        self.mitigationStr.setLineWrap(True)
        self.mitigationStr.setBounds(10, 320, 555, 175)

        mitigationStrScroll = JScrollPane(self.mitigationStr)
        mitigationStrScroll.setBounds(10, 320, 555, 175)
        mitigationStrScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED)

        self.pnl = JPanel()
        self.pnl.setBounds(0, 0, 1000, 1000);
        self.pnl.setLayout(None);
        self.pnl.add(addSSBtn)
        self.pnl.add(piclistLabel)
        self.pnl.add(nameLabel)
        self.pnl.add(deleteSSBtn)
        self.pnl.add(rmVulnButton)
        self.pnl.add(severityLabel)
        self.pnl.add(mitigationLabel)
        self.pnl.add(descriptionLabel)
        self.pnl.add(previewPicLabel)
        self.pnl.add(mitigationStrScroll)
        self.pnl.add(descriptionStringScroll)
        self.pnl.add(self.ssList)
        self.pnl.add(self.firstPic)
        self.pnl.add(self.addButton)
        self.pnl.add(self.vulnName)
        self.pnl.add(self.threatLevel)
        self.pnl.add(self.colorCombo)
        
    def initProjSettingsTab(self):
        # init project settings 
        
        projNameLabel = JLabel("Name:")
        projNameLabel.setBounds(10, 50, 140, 30)

        self.projName = JTextField("")
        self.projName.setBounds(140, 50, 320, 30)
        self.projName.getDocument().addDocumentListener(projTextChanged(self))

        detailsLabel = JLabel("Details:")
        detailsLabel.setBounds(10, 120, 140, 30)

        reportLabel = JLabel("Generate Report:")
        reportLabel.setBounds(10, 375, 140, 30)

        types = ["DOCX","HTML","XLSX"]
        self.reportType = JComboBox(types)
        self.reportType.setBounds(10, 400, 140, 30)

        generateReportButton = JButton("Generate", actionPerformed=self.generateReport)
        generateReportButton.setBounds(160, 400, 90, 30)


        self.projDetails = JTextArea("", 5, 30)
        self.projDetails.setWrapStyleWord(True);
        self.projDetails.setLineWrap(True)

        projDetailsScroll = JScrollPane(self.projDetails)
        projDetailsScroll.setBounds(10, 150, 450, 175)
        projDetailsScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED)

        projPathLabel = JLabel("Path:")
        projPathLabel.setBounds(10, 90, 140, 30)

        self.projPath = JTextField("")
        self.projPath.setBounds(140, 90, 320, 30)

        chooseProjPathButton = JButton("Browse...",actionPerformed=self.chooseProjPath)
        chooseProjPathButton.setBounds(470, 90, 100, 30)
        
        importProjButton = JButton("Import",actionPerformed=self.importProj)
        importProjButton.setBounds(470, 10, 100, 30)

        exportProjButton = JButton("Export",actionPerformed=self.exportProj)
        exportProjButton.setBounds(575, 10, 100, 30)

        openProjButton = JButton("Open Directory",actionPerformed=self.openProj)
        openProjButton.setBounds(680, 10, 130, 30)

        currentProjectLabel = JLabel("Current:")
        currentProjectLabel.setBounds(10, 10, 140, 30)

        projects = self.config.options('projects')
        self.currentProject = JComboBox(projects)
        self.currentProject.addActionListener(projectChangeHandler(self))
        self.currentProject.setBounds(140, 10, 140, 30)

        self.autoSave = JCheckBox("Auto Save Mode")
        self.autoSave.setEnabled(False)  # implement this feature
        self.autoSave.setBounds(300, 10, 140, 30)
        self.autoSave.setToolTipText("Will save any changed value while focus is out")

        addProjButton = JButton("Add / Update",actionPerformed=self.addProj)
        addProjButton.setBounds(10, 330, 150, 30)

        removeProjButton = JButton("Remove Current",actionPerformed=self.rmProj)
        removeProjButton.setBounds(315, 330, 146, 30)

        generalOptions = self.config.options('general')
        if 'default project' in generalOptions:
            defaultProj = self.config.get('general','default project')
            self.currentProject.getModel().setSelectedItem(defaultProj)
            self.projPath.setText(self.config.get('projects',self.currentProject.getSelectedItem()))

        self.clearProjTab = True
        self.projectSettings = JPanel()
        self.projectSettings.setBounds(0, 0, 1000, 1000)
        self.projectSettings.setLayout(None)
        self.projectSettings.add(reportLabel)
        self.projectSettings.add(detailsLabel)
        self.projectSettings.add(projPathLabel)
        self.projectSettings.add(addProjButton)
        self.projectSettings.add(openProjButton)
        self.projectSettings.add(projNameLabel)
        self.projectSettings.add(projDetailsScroll)
        self.projectSettings.add(importProjButton)
        self.projectSettings.add(exportProjButton)
        self.projectSettings.add(removeProjButton)
        self.projectSettings.add(generateReportButton)
        self.projectSettings.add(chooseProjPathButton)
        self.projectSettings.add(currentProjectLabel)
        self.projectSettings.add(self.projPath)
        self.projectSettings.add(self.autoSave)
        self.projectSettings.add(self.projName)
        self.projectSettings.add(self.reportType)
        self.projectSettings.add(self.currentProject)

    def initTabs(self):
        #
        ##  init autorize tabs
        #
        
        self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT)
        self.scrollPane = JScrollPane(self.logTable)
        self._splitpane.setLeftComponent(self.scrollPane)
        colorsMenu = JMenu("Paint")
        redMenu = JMenuItem("Red")
        noneMenu = JMenuItem("None")
        greenMenu = JMenuItem("Green")
        redMenu.addActionListener(paintChange(self, "Red"))
        noneMenu.addActionListener(paintChange(self, None))
        greenMenu.addActionListener(paintChange(self, "Green"))
        colorsMenu.add(redMenu)
        colorsMenu.add(noneMenu)
        colorsMenu.add(greenMenu)
        
        
        self.menu = JPopupMenu("Popup")
        self.menu.add(colorsMenu)

        self.tabs = JTabbedPane()
        
        self.tabs.addTab("Request", self._requestViewer.getComponent())
        self.tabs.addTab("Response", self._responseViewer.getComponent())

        self.tabs.addTab("Vulnerability", self.pnl)

        self.tabs.addTab("Project Settings", self.projectSettings)
        
        self.tabs.setSelectedIndex(2)
        self._splitpane.setRightComponent(self.tabs)

    def initCallbacks(self):
        #
        ##  init callbacks
        #

        # customize our UI components
        self._callbacks.customizeUiComponent(self._splitpane)
        self._callbacks.customizeUiComponent(self.logTable)
        self._callbacks.customizeUiComponent(self.scrollPane)
        self._callbacks.customizeUiComponent(self.tabs)
        self._callbacks.registerContextMenuFactory(self)
        # add the custom tab to Burp's UI
        self._callbacks.addSuiteTab(self)


    def loadVulnerabilities(self, projPath):
        self.clearList(None)
        selected = False
        for root, dirs, files in os.walk(projPath): # make it go only for dirs
            for dirName in dirs:
                xmlPath = projPath+"/"+dirName+"/vulnerability.xml"
                # xmlPath = xmlPath.replace("/","//")
                document = self.getXMLDoc(xmlPath)
                nodeList = document.getDocumentElement().getChildNodes()
                vulnName = nodeList.item(0).getTextContent()
                severity = nodeList.item(1).getTextContent()
                description = nodeList.item(2).getTextContent()
                mitigation = nodeList.item(3).getTextContent()
                color = nodeList.item(4).getTextContent()
                test = vulnerability(vulnName,severity,description,mitigation,color)
                self._lock.acquire()
                row = self._log.size()
                self._log.add(test)
                self.fireTableRowsInserted(row, row)
                self._lock.release()
                if vulnName == self.vulnName.getText():
                    self.logTable.setRowSelectionInterval(row,row)
                    selected = True
        if selected == False and self._log.size() > 0:
            self.logTable.setRowSelectionInterval(0, 0)
            self.loadVulnerability(self._log.get(0))
        
    def createSection(self, sectioName):
        self.config.read('config.ini')
        if not (sectioName in self.config.sections()):
            self.config.add_section(sectioName)
            cfgfile = open("config.ini",'w')
            self.config.write(cfgfile)
            cfgfile.close()

    def saveCfg(self):
        f = open('config.ini', 'w')
        self.config.write(f)
        f.close()

    def getXMLDoc(self, xmlPath):
        try:
            document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlPath)
            return document
        except:
            self._extender.popup("XML file not found")
            return

    def saveXMLDoc(self, doc, xmlPath):
        transformerFactory = TransformerFactory.newInstance()
        transformer = transformerFactory.newTransformer()
        source = DOMSource(doc)
        result = StreamResult(File(xmlPath))
        transformer.transform(source, result)

    def generateReport(self,event):
        if self.reportType.getSelectedItem() == "HTML":
            path = self.reportToHTML()
        if self.reportType.getSelectedItem() == "XLSX":
            path = self.reportToXLS()
        if self.reportType.getSelectedItem() == "DOCX":
            path = self.generateReportFromDocxTemplate('template.docx',"newfile.docx", 'word/document.xml')
        n = JOptionPane.showConfirmDialog(None, "Report generated successfuly:\n%s\nWould you like to open it?" % (path), "PT Manager", JOptionPane.YES_NO_OPTION)
        if n == JOptionPane.YES_OPTION:
            os.system('"' + path + '"') # Bug! stucking burp until the file get closed

    def exportProj(self,event):
        self.chooser.setDialogTitle("Save project")
        Ffilter = FileNameExtensionFilter("Zip files", ["zip"])
        self.chooser.setFileFilter(Ffilter)
        returnVal = self.chooser.showSaveDialog(None)
        if returnVal == JFileChooser.APPROVE_OPTION:
            dst = str(self.chooser.getSelectedFile())
            shutil.make_archive(dst,"zip",self.getCurrentProjPath())
            self.popup("Project export successfuly")

    def importProj(self,event):
        self.chooser.setDialogTitle("Select project zip to directory")
        Ffilter = FileNameExtensionFilter("Zip files", ["zip"])
        self.chooser.setFileFilter(Ffilter)
        returnVal = self.chooser.showOpenDialog(None)
        if returnVal == JFileChooser.APPROVE_OPTION:
            zipPath = str(self.chooser.getSelectedFile())
            self.chooser.setDialogTitle("Select project directory")
            self.chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
            returnVal = self.chooser.showOpenDialog(None)
            if returnVal == JFileChooser.APPROVE_OPTION:
                projPath = str(self.chooser.getSelectedFile()) + "/PTManager"
                with zipfile.ZipFile(zipPath, "r") as z:
                    z.extractall(projPath)

                xmlPath = projPath + "/project.xml"
                document = self.getXMLDoc(xmlPath)
                nodeList = document.getDocumentElement().getChildNodes()
                projName = nodeList.item(0).getTextContent()
                nodeList.item(1).setTextContent(projPath)
                self.saveXMLDoc(document, xmlPath)
                self.config.set('projects', projName, projPath)
                self.saveCfg()
                self.reloadProjects()
                self.currentProject.getModel().setSelectedItem(projName)
                self.clearVulnerabilityTab() 

    def reportToXLS(self):
        if not xlsxwriterImported:
            self.popup("xlsxwriter library is not imported")
            return
        workbook = xlsxwriter.Workbook(self.getCurrentProjPath() + '/PT Manager Report.xlsx')
        worksheet = workbook.add_worksheet()
        bold = workbook.add_format({'bold': True})
        worksheet.write(0, 0, "Vulnerability Name", bold)
        worksheet.write(0, 1, "Threat Level", bold)
        worksheet.write(0, 2, "Description", bold)
        worksheet.write(0, 3, "Mitigation", bold)
        row = 1
        for i in range(0,self._log.size()):
            worksheet.write(row, 0, self._log.get(i).getName())
            worksheet.write(row, 1, self._log.get(i).getSeverity())
            worksheet.write(row, 2, self._log.get(i).getDescription())
            worksheet.write(row, 3, self._log.get(i).getMitigation())
            row = row + 1
            # add requests and images as well
        workbook.close()
        return self.getCurrentProjPath() + '/PT Manager Report.xlsx'
        
    def reportToHTML(self):
        htmlContent = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="he" dir="ltr">
    <head>
        <title>PT Manager Report</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <style>
        body {
        background-repeat: no-repeat;
        background-attachment: fixed;
        font-family: Arial,Tahoma,sens-serif;
        font-size: 13px;
        margin: auto;
        }

        #warpcenter {
            width: 900px;
            margin: 0px auto;
        }

        table {
            border: 2px dashed #000000;
        }

        td {
            border-top: 2px dashed #000000;
            padding: 10px;
        }

        img {
                border: 0px;
        }
</style>
<script language="javascript">
    function divHideShow(divToHideOrShow) 
    {
        var div = document.getElementById(divToHideOrShow);

        if (div.style.display == "block") 
        {
            div.style.display = "none";
        }
        else 
        {
            div.style.display = "block";
        }

        
    }         
</script>
    </head>

    <body>
        <div id="warpcenter">

<h1> PT Manager Report </h1>
<h2> Project: %s</h1>
    """ % (self.projName.getText())

        for i in range(0,self._log.size()):
            name = self._log.get(i).getName()
            request = "None"
            response = "None"
            path = self.getVulnReqResPath("request",name)
            if os.path.exists(path):
                request = self.newlineToBR(self.getFileContent(path))
                
            path = self.getVulnReqResPath("response",name)
            if os.path.exists(path):
                response = self.newlineToBR(self.getFileContent(path))
            images = ""
            for fileName in os.listdir(self.projPath.getText()+"/"+self.clearStr(name)):
                if fileName.endswith(".jpg"):
                    images += "%s<br><img src=\"%s\"><br><br>" % (fileName, self.projPath.getText()+"/"+self.clearStr(name) + "/" + fileName)
            description = self.newlineToBR(self._log.get(i).getDescription())
            mitigation = self.newlineToBR(self._log.get(i).getMitigation())
            htmlContent +=  self.convertVulntoTable(i,name,self._log.get(i).getSeverity(), description,mitigation, request, response, images)
        htmlContent += "</div></body></html>"
        f = open(self.getCurrentProjPath() + '/PT Manager Report.html', 'w')
        f.writelines(htmlContent)
        f.close()
        return self.getCurrentProjPath() + '/PT Manager Report.html'

    def newlineToBR(self,string):
        return "<br />".join(string.split("\n"))

    def getFileContent(self,path):
        f = open(path, "rb")
        content = f.read()
        f.close()
        return content

    def convertVulntoTable(self, number, name, severity, description, mitigation, request = "None", response = "None", images = "None"):
        return """<div style="width: 100%%;height: 30px;text-align: center;background-color:#E0E0E0;font-size: 17px;font-weight: bold;color: #000;padding-top: 10px;">%s <a href="javascript:divHideShow('Table_%s');" style="color:#191970">(OPEN / CLOSE)</a></div>
        <div id="Table_%s" style="display: none;">
            <table width="100%%" cellspacing="0" cellpadding="0" style="margin: 0px auto;text-align: left;border-top: 0px;">
                <tr>
                    <td>
                        <div style="font-size: 16px;font-weight: bold;">
                        <span style="color:#000000">Threat Level: </span> 
                        <span style="color:#8b8989">%s</span>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td>
                        <div style="font-size: 16px;font-weight: bold;">
                        <span style="color:#000000">Description</span> 
                        <a href="javascript:divHideShow('Table_%s_Command_03');" style="color:#191970">OPEN / CLOSE >>></a>
                        </div>

                        <div id="Table_%s_Command_03" style="display: none;margin-top: 25px;">
                        %s
                        </div>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td>
                        <div style="font-size: 16px;font-weight: bold;">
                        <span style="color:#000000">Mitigration</span> 
                        <a href="javascript:divHideShow('Table_%s_Command_04');" style="color:#191970">OPEN / CLOSE >>></a>
                        </div>

                        <div id="Table_%s_Command_04" style="display: none;margin-top: 25px;">
                        %s
                        <b>
                                            </td>
                                        </tr>

                                        <tr>
                                            <td>
                        <div style="font-size: 16px;font-weight: bold;">
                        <span style="color:#000000">Request</span> 
                        <a href="javascript:divHideShow('Table_%s_Command_05');" style="color:#191970">OPEN / CLOSE >>></a>
                        </div>

                        <div id="Table_%s_Command_05" style="display: none;margin-top: 25px;">
                        %s
                        <b>
                                            </td>
                                        </tr>


                                                        <tr>
                                            <td>
                        <div style="font-size: 16px;font-weight: bold;">
                        <span style="color:#000000">Response</span> 
                        <a href="javascript:divHideShow('Table_%s_Command_06');" style="color:#191970">OPEN / CLOSE >>></a>
                        </div>

                        <div id="Table_%s_Command_06" style="display: none;margin-top: 25px;">
                        %s
                        <b>
                                            </td>
                                        </tr>

                                                        <tr>
                                            <td>
                        <div style="font-size: 16px;font-weight: bold;">
                        <span style="color:#000000">Images</span> 
                        <a href="javascript:divHideShow('Table_%s_Command_07');" style="color:#191970">OPEN / CLOSE >>></a>
                        </div>

                        <div id="Table_%s_Command_07" style="display: none;margin-top: 25px;">
                        %s
                        <b>
                    </td>
                </tr>
            </table>
        </div><br><br>""" % (name,number,number,severity,number,number,description,number,number,mitigation,number,number,request,number,number,response,number,number,images)

    def clearVulnerabilityTab(self, rmVuln=True):
        if rmVuln:
            self.vulnName.setText("")
        self.descriptionString.setText("")
        self.mitigationStr.setText("")
        self.colorCombo.setSelectedIndex(0)
        self.threatLevel.setSelectedIndex(0)
        self.screenshotsList.clear()
        self.addButton.setText("Add")
        self.firstPic.setIcon(None)

    def saveRequestResponse(self, type, requestResponse, vulnName):
        path = self.getVulnReqResPath(type,vulnName)
        f = open(path, 'wb')
        f.write(requestResponse)
        f.close()

    def openProj(self, event):
        os.system('explorer ' + self.projPath.getText())

    def getVulnReqResPath(self, requestOrResponse, vulnName):
        return self.getCurrentProjPath() + "/" + self.clearStr(vulnName) + "/"+requestOrResponse+"_" + self.clearStr(vulnName)

    def htmlEscape(self,data):
        return data.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;')

    def generateReportFromDocxTemplate(self, zipname, newZipName, filename):      
        newZipName = self.getCurrentProjPath() + "/" + newZipName
        with zipfile.ZipFile(zipname, 'r') as zin:
            with zipfile.ZipFile(newZipName, 'w') as zout:
                zout.comment = zin.comment
                for item in zin.infolist():
                    if item.filename != filename:
                        zout.writestr(item, zin.read(item.filename))
                    else:
                        xml_content = zin.read(item.filename)
                        result = re.findall("(.*)<w:body>(?:.*)<\/w:body>(.*)",xml_content)[0]
                        newXML = result[0]
                        templateBody = re.findall("<w:body>(.*)<\/w:body>", xml_content)[0]
                        newBody = ""

                        for i in range(0,self._log.size()):
                            tmp = templateBody
                            tmp = tmp.replace("$vulnerability", self.htmlEscape(self._log.get(i).getName()))
                            tmp = tmp.replace("$severity", self.htmlEscape(self._log.get(i).getSeverity()))
                            tmp = tmp.replace("$description", self.htmlEscape(self._log.get(i).getDescription()))
                            tmp = tmp.replace("$mitigation", self.htmlEscape(self._log.get(i).getMitigation()))
                            newBody = newBody + tmp
                         
                        newXML = newXML + newBody
                        newXML = newXML + result[1]

        with zipfile.ZipFile(newZipName, mode='a', compression=zipfile.ZIP_DEFLATED) as zf:
            zf.writestr(filename, newXML)
        return newZipName


    def chooseProjPath(self, event):
        self.chooser.setDialogTitle("Select target directory")
        self.chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
        returnVal = self.chooser.showOpenDialog(None)
        if returnVal == JFileChooser.APPROVE_OPTION:
            projPath = str(self.chooser.getSelectedFile()) + "/PTManager"
            os.makedirs(projPath)
            self.projPath.setText(projPath)

    def reloadProjects(self):
        self.currentProject.setModel(DefaultComboBoxModel(self.config.options('projects')))

    def rmProj(self, event):
        if self.popUpAreYouSure() == JOptionPane.YES_OPTION:
            self._requestViewer.setMessage("None", False)
            self._responseViewer.setMessage("None", False)
            shutil.rmtree(self.projPath.getText())
            self.config.remove_option('projects',self.currentProject.getSelectedItem())
            self.reloadProjects()
            self.currentProject.setSelectedIndex(0)
            self.loadVulnerabilities(self.projPath.getText())

    def popup(self,msg):
        JOptionPane.showMessageDialog(None,msg)

    def addProj(self, event):
        projPath = self.projPath.getText()
        if projPath == None or projPath == "":
            self.popup("Please select path")
            return
        self.config.set('projects', self.projName.getText(), projPath)
        self.saveCfg()
        xml = ET.Element('project')
        name = ET.SubElement(xml, "name")
        path = ET.SubElement(xml, "path")
        details = ET.SubElement(xml, "details")
        autoSaveMode = ET.SubElement(xml, "autoSaveMode")

        name.text = self.projName.getText()
        path.text = projPath
        details.text = self.projDetails.getText()
        autoSaveMode.text = str(self.autoSave.isSelected())
        tree = ET.ElementTree(xml)
        try:
            tree.write(self.getCurrentProjPath()+'/project.xml')
        except:
            self.popup("Invalid path")
            return

        self.reloadProjects()
        self.clearVulnerabilityTab()
        self.clearList(None)
        self.currentProject.getModel().setSelectedItem(self.projName.getText())

    def resize(self, image, width, height):
        bi = BufferedImage(width, height, BufferedImage.TRANSLUCENT)
        g2d = bi.createGraphics()
        g2d.addRenderingHints(RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY))
        g2d.drawImage(image, 0, 0, width, height, None)
        g2d.dispose()
        return bi;

    def clearStr(self, var):
        return var.replace(" " , "_").replace("\\" , "").replace("/" , "").replace(":" , "").replace("*" , "").replace("?" , "").replace("\"" , "").replace("<" , "").replace(">" , "").replace("|" , "").replace("(" , "").replace(")" , "")

    def popUpAreYouSure(self):
        dialogResult = JOptionPane.showConfirmDialog(None,"Are you sure?","Warning",JOptionPane.YES_NO_OPTION)
        if dialogResult == 0:
            return 0
        return 1

    def removeSS(self,event):
        if self.popUpAreYouSure() == JOptionPane.YES_OPTION:
            os.remove(self.getCurrentVulnPath() + "/" + self.ssList.getSelectedValue())
            self.ssList.getModel().remove(self.ssList.getSelectedIndex())
            self.firstPic.setIcon(ImageIcon(None))
            # check if there is images and select the first one
            # bug in linux

    def addSS(self,event):
        clipboard = Toolkit.getDefaultToolkit().getSystemClipboard()
        try:
            image = clipboard.getData(DataFlavor.imageFlavor)
        except:
            self.popup("Clipboard not contains image")
            return
        vulnPath = self.projPath.getText() + "/" + self.clearStr(self.vulnName.getText())
        if not os.path.exists(vulnPath):
            os.makedirs(vulnPath)
        name = self.clearStr(self.vulnName.getText()) + str(random.randint(1, 99999))+".jpg"
        fileName = self.projPath.getText()+"/"+ self.clearStr(self.vulnName.getText()) + "/" + name
        file = File(fileName)
        bufferedImage = BufferedImage(image.getWidth(None), image.getHeight(None), BufferedImage.TYPE_INT_RGB);
        g = bufferedImage.createGraphics();
        g.drawImage(image, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), Color.WHITE, None);
        ImageIO.write(bufferedImage, "jpg", file)
        self.addVuln(self)
        self.ssList.setSelectedValue(name,True)

    def rmVuln(self, event):
        if self.popUpAreYouSure() == JOptionPane.YES_OPTION:
            self._requestViewer.setMessage("None", False)
            self._responseViewer.setMessage("None", False)
            shutil.rmtree(self.getCurrentVulnPath())
            self.clearVulnerabilityTab()
            self.loadVulnerabilities(self.getCurrentProjPath())

    def addVuln(self, event):
        if self.colorCombo.getSelectedItem() == "Color:":
            colorTxt = None
        else:
            colorTxt = self.colorCombo.getSelectedItem()
        self._lock.acquire()
        row = self._log.size()
        vulnObject = vulnerability(self.vulnName.getText(),self.threatLevel.getSelectedItem(),self.descriptionString.getText(),self.mitigationStr.getText() ,colorTxt)
        self._log.add(vulnObject) 
        self.fireTableRowsInserted(row, row)
        self._lock.release()

        vulnPath = self.projPath.getText() + "/" + self.clearStr(self.vulnName.getText())
        if not os.path.exists(vulnPath):
            os.makedirs(vulnPath)

        xml = ET.Element('vulnerability')
        name = ET.SubElement(xml, "name")
        severity = ET.SubElement(xml, "severity")
        description = ET.SubElement(xml, "description")
        mitigation = ET.SubElement(xml, "mitigation")
        color = ET.SubElement(xml, "color")
        name.text = self.vulnName.getText()
        severity.text = self.threatLevel.getSelectedItem()
        description.text = self.descriptionString.getText()
        mitigation.text = self.mitigationStr.getText()
        color.text = colorTxt
        tree = ET.ElementTree(xml)
        tree.write(vulnPath+'/vulnerability.xml')

        self.loadVulnerabilities(self.getCurrentProjPath())
        self.loadVulnerability(vulnObject)

    def vulnNameChanged(self):
            if os.path.exists(self.getCurrentVulnPath()) and self.vulnName.getText() != "":
                self.addButton.setText("Update")
            elif self.addButton.getText() != "Add":
                options = ["Create a new vulnerability", "Change current vulnerability name"]
                n = JOptionPane.showOptionDialog(None,
                    "Would you like to?",
                    "Vulnerability Name",
                    JOptionPane.YES_NO_CANCEL_OPTION,
                    JOptionPane.QUESTION_MESSAGE,
                    None,
                    options,
                    options[0]);

                if n == 0:
                    self.clearVulnerabilityTab(False)
                    self.addButton.setText("Add")
                else:
                    newName = JOptionPane.showInputDialog(
                    None,
                    "Enter new name:",
                    "Vulnerability Name",
                    JOptionPane.PLAIN_MESSAGE,
                    None,
                    None,
                    self.vulnName.getText())
                    row = self.logTable.getSelectedRow()
                    old = self.logTable.getValueAt(row,1)                   
                    self.changeVulnName(newName,old)
                
    def changeVulnName(self,new,old):
        newpath = self.getCurrentProjPath() + "/" + new
        oldpath = self.getCurrentProjPath() + "/" + old
        os.rename(oldpath,newpath)
        self.changeCurrentVuln(new,0, newpath + "/vulnerability.xml")

    def getCurrentVulnPath(self):
        return self.projPath.getText() + "/" + self.clearStr(self.vulnName.getText())

    def getCurrentProjPath(self):
        return self.projPath.getText()

    def loadSS(self, imgPath):
        image = ImageIO.read(File(imgPath))
        if image.getWidth() <= 550 and image.getHeight() <= 400:
            self.firstPic.setIcon(ImageIcon(image))
            self.firstPic.setSize(image.getWidth(),image.getHeight())
        else:
            self.firstPic.setIcon(ImageIcon(self.resize(image,550, 400)))
            self.firstPic.setSize(550,400)

    def clearProjectTab(self):
        self.projPath.setText("")
        self.projDetails.setText("")

    def clearList(self, event):
        self._lock.acquire()
        self._log = ArrayList()
        row = self._log.size()
        self.fireTableRowsInserted(row, row)
        self._lock.release()

    #
    # implement IContextMenuFactory
    #
    def createMenuItems(self, invocation):
        responses = invocation.getSelectedMessages();
        if responses > 0:
            ret = LinkedList()
            requestMenuItem = JMenuItem("Send to PT Manager");
            requestMenuItem.addActionListener(handleMenuItems(self,responses[0], "request"))
            ret.add(requestMenuItem);
            return(ret);
        return null;
    #
    # implement ITab
    #
    def getTabCaption(self):
        return "PT Manager"
    
    def getUiComponent(self):
        return self._splitpane

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

    def getColumnCount(self):
        return 3

    def getColumnName(self, columnIndex):
        if columnIndex == 0:
            return "#"
        if columnIndex == 1:
            return "Vulnerability Name"
        if columnIndex == 2:
            return "Threat Level"
        return ""

    def getValueAt(self, rowIndex, columnIndex):
        vulnObject = self._log.get(rowIndex)
        if columnIndex == 0:
            return rowIndex+1
        if columnIndex == 1:
            return vulnObject.getName()
        if columnIndex == 2:
            return vulnObject.getSeverity()
        if columnIndex == 3:
            return vulnObject.getMitigation()
        if columnIndex == 4:
            return vulnObject.getColor()

        return ""

    def changeCurrentVuln(self,value,fieldNumber, xmlPath = "def"):
        if xmlPath == "def":
            xmlPath = self.getCurrentVulnPath() + "/vulnerability.xml"
        document = self.getXMLDoc(xmlPath)
        nodeList = document.getDocumentElement().getChildNodes()
        nodeList.item(fieldNumber).setTextContent(value)
        self.saveXMLDoc(document, xmlPath)
        self.loadVulnerabilities(self.getCurrentProjPath())

    def loadVulnerability(self, vulnObject):
        self.addButton.setText("Update")
        self.vulnName.setText(vulnObject.getName())
        self.threatLevel.setSelectedItem(vulnObject.getSeverity())
        self.descriptionString.setText(vulnObject.getDescription())
        self.mitigationStr.setText(vulnObject.getMitigation())

        if vulnObject.getColor() == "" or vulnObject.getColor() == None:
            self.colorCombo.setSelectedItem("Color:")
        else:
            self.colorCombo.setSelectedItem(vulnObject.getColor())
        self.screenshotsList.clear()

        for fileName in os.listdir(self.projPath.getText()+"/"+self.clearStr(vulnObject.getName())):
            if fileName.endswith(".jpg"):
                self.screenshotsList.addElement(fileName)
                imgPath = self.projPath.getText()+"/"+self.clearStr(vulnObject.getName())+'/'+fileName
                # imgPath = imgPath.replace("/","//")
                self.loadSS(imgPath)

        if (self.screenshotsList.getSize() == 0):
            self.firstPic.setIcon(None)
        else:
            self.ssList.setSelectedIndex(0)

        path = self.getVulnReqResPath("request",vulnObject.getName())
        if os.path.exists(path):
            f = self.getFileContent(path)
            self._requestViewer.setMessage(f, False)
        else:
            self._requestViewer.setMessage("None", False)
        
        path = self.getVulnReqResPath("response",vulnObject.getName())
        if os.path.exists(path):
            f = self.getFileContent(path)
            self._responseViewer.setMessage(f, False)
        else:
            self._responseViewer.setMessage("None", False)
Esempio n. 16
0
class main(JFrame):
    def __init__(self):
        super(main,self).__init__()
        self.Config()
        self.windows()
        self.ruta=""

    def windows(self):
        self.setTitle("IDE Meta Compilador")
        self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
        self.setLayout(None)
        self.setLocationRelativeTo(None)
        self.setVisible(True)



    def Config(self):
        self.panel = JScrollPane()
        self.txtArea_Principal =JTextArea()
        self.jScrollPane1 =JScrollPane()
        self.txtTerminal =JTextArea()
        self.Menu =JMenuBar()
        self.menu_Archivo =JMenu()
        self.menu_Nuevo =JMenuItem()
        self.menuabrir =JMenuItem()
        self.menucerrar =JMenuItem()
        self.menuguardar =JMenuItem()
        self.menuguardarcomo =JMenuItem()
        self.menusalir =JMenuItem()
        self.menu_Edicion =JMenu()
        self.menu_cortar =JMenuItem()
        self.menu_copiar =JMenuItem()
        self.menu_pegar =JMenuItem()
        self.menu_Tablas =JMenu()
        self.menu_TablasEstaticas =JMenu()
        self.submenu_palabrasReservadas =JMenuItem()
        self.submenu_CaracteresEspeciales =JMenuItem()
        self.submenu_operadores =JMenu()
        self.ta_di_conu_enteros =JMenuItem()
        self.ta_di_conu_reales =JMenuItem()
        self.ta_di_conu_cientificos =JMenuItem()
        self.menu_TablaasDinamicas =JMenu()
        self.submenu_simbolos =JMenuItem()
        self.submenu_identificadores =JMenuItem()
        self.submenu_errores =JMenuItem()
        self.submenu_constantesNumericas =JMenu()
        self.ta_es_op_aritmeticos =JMenuItem()
        self.ta_es_op_relacionales =JMenuItem()
        self.ta_es_op_logicos =JMenuItem()
        self.submenu_Constantes_No_Numericas =JMenu()
        self.tab_caracteres =JMenuItem()
        self.tab_cadenas =JMenuItem()
        self.menu_Analisis =JMenu()
        self.ana_lexico =JMenuItem()
        self.ana_sintactico =JMenuItem()
        self.ana_semantico =JMenuItem()
        self.menu_Acerca_de =JMenu()
        self.btn_integrantes =JMenuItem()
        #########################
        self.jf = JFileChooser()

        #########################


        self.txtArea_Principal.setColumns(20)
        self.txtArea_Principal.setRows(5)
        self.txtArea_Principal.setAutoscrolls(False)
        self.txtArea_Principal.setEnabled(False)
        self.panel.setViewportView(self.txtArea_Principal)
        self.getContentPane().add(self.panel)
        self.panel.setBounds(0, 0, 1080, 450)


        self.txtTerminal.setColumns(20)
        self.txtTerminal.setRows(5)
        self.txtTerminal.setAutoscrolls(False)
        self.txtTerminal.setFocusable(False)
        self.jScrollPane1.setViewportView(self.txtTerminal)

        self.getContentPane().add(self.jScrollPane1)
        self.jScrollPane1.setBounds(0, 460, 1080, 150)
        # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>MENU ARCHIVOS<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        self.menu_Archivo.setText("Archivo")
        
        self.menu_Nuevo.addActionListener(lambda event : self.nuevo(event))
        self.menu_Nuevo.setText("Nuevo")
        self.menu_Archivo.add(self.menu_Nuevo)

        self.menuabrir.setText("Abrir")
        self.menuabrir.addActionListener(lambda event : self.abrir(event))
        self.menu_Archivo.add(self.menuabrir)

        self.menucerrar.setText("Cerrar")
        self.menucerrar.addActionListener(lambda event : self.cerrar(event))
        self.menu_Archivo.add(self.menucerrar)

        self.menuguardar.setText("Guardar")
        self.menuguardar.addActionListener(lambda event : self.guardar(event))
        self.menu_Archivo.add(self.menuguardar)
        
        self.menuguardarcomo.setText("Guardar como")
        self.menuguardarcomo.addActionListener(lambda event : self.guardarcomo(event))
        self.menu_Archivo.add(self.menuguardarcomo)

        self.menusalir.setText("Salir")
        self.menusalir.addActionListener(lambda event : self.salir(event))
        self.menu_Archivo.add(self.menusalir)
        
        
        self.Menu.add(self.menu_Archivo)
        # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>MENU EDICION<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

        self.menu_Edicion.setText("Edicion")

        self.menu_cortar.setText("Cortar")
        self.menu_cortar.addActionListener(lambda event : self.cortar(event))
        self.menu_Edicion.add(self.menu_cortar)

        self.menu_copiar.setText("Copiar")
        self.menu_copiar.addActionListener(lambda event : self.copiar(event))
        self.menu_Edicion.add(self.menu_copiar)

        self.menu_pegar.setText("Pegar")
        self.menu_pegar.addActionListener(lambda event : self.pegar(event))
        self.menu_Edicion.add(self.menu_pegar)

        self.Menu.add(self.menu_Edicion)
        # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>MENU TABLAS<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

        self.menu_Tablas.setText("Tablas")

        self.menu_TablasEstaticas.setText("Tablas Estaticas")

        self.submenu_palabrasReservadas.setText("Tabla de palabras reservadas")
        self.menu_TablasEstaticas.add(self.submenu_palabrasReservadas)

        self.submenu_CaracteresEspeciales.setText("Tabla de caracteres especiales")
        self.menu_TablasEstaticas.add(self.submenu_CaracteresEspeciales)

        self.submenu_operadores.setText("Tabla de operadores")

        self.ta_es_op_aritmeticos.setText("Aritmeticos")
        self.submenu_operadores.add(self.ta_es_op_aritmeticos)

        self.ta_es_op_relacionales.setText("Relacionales")
        self.submenu_operadores.add(self.ta_es_op_relacionales)

        self.ta_es_op_logicos.setText("Logicos")
        self.submenu_operadores.add(self.ta_es_op_logicos)

        self.menu_TablasEstaticas.add(self.submenu_operadores)

        self.menu_Tablas.add(self.menu_TablasEstaticas)

        self.menu_TablaasDinamicas.setText("Tablas Dinamicas")

        self.submenu_simbolos.setText("Tabla de simbolos")
        self.menu_TablaasDinamicas.add(self.submenu_simbolos)

        self.submenu_identificadores.setText("Tabla de identificadores")
        self.menu_TablaasDinamicas.add(self.submenu_identificadores)

        self.submenu_errores.setText("Tabla de errores")
        self.menu_TablaasDinamicas.add(self.submenu_errores)

        self.submenu_constantesNumericas.setText("Tabla de constantes numericas")

        self.ta_di_conu_enteros.setText("Enteros")
        self.ta_di_conu_enteros.addActionListener(lambda event : self.numeroenteros(event))        
        self.submenu_constantesNumericas.add(self.ta_di_conu_enteros)

        self.ta_di_conu_reales.setText("Reales")
        self.ta_di_conu_reales.addActionListener(lambda event : self.numeroreales(event))
        self.submenu_constantesNumericas.add(self.ta_di_conu_reales)

        self.ta_di_conu_cientificos.setText("Cientificos")
        self.submenu_constantesNumericas.add(self.ta_di_conu_cientificos)

        self.menu_TablaasDinamicas.add(self.submenu_constantesNumericas)

        self.submenu_Constantes_No_Numericas.setText("Tabla de constantes no numericas")

        self.tab_caracteres.setText("Caracteres")
        self.submenu_Constantes_No_Numericas.add(self.tab_caracteres)

        self.tab_cadenas.setText("Cadenas")
        self.submenu_Constantes_No_Numericas.add(self.tab_cadenas)

        self.menu_TablaasDinamicas.add(self.submenu_Constantes_No_Numericas)

        self.menu_Tablas.add(self.menu_TablaasDinamicas)

        self.Menu.add(self.menu_Tablas)

        # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>MENU ANALISIS<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        
        self.menu_Analisis.setText("Analisis")

        self.ana_lexico.setText("Lexico")
        self.ana_lexico.addActionListener(lambda event : self.lexico(event))
        self.menu_Analisis.add(self.ana_lexico)

        self.ana_sintactico.setText("Sintactico")
        self.ana_sintactico.addActionListener(lambda event : self.sintactico(event))        
        self.menu_Analisis.add(self.ana_sintactico)

        self.ana_semantico.setText("Semantico")
        self.menu_Analisis.add(self.ana_semantico)

        self.Menu.add(self.menu_Analisis)

        # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>MENU ACERCA DE<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

        self.menu_Acerca_de.setText("Acerca de")

        self.btn_integrantes.setText("Integrante del proyecto")
        self.btn_integrantes.addActionListener(lambda event : self.integrantes(event))
        self.menu_Acerca_de.add(self.btn_integrantes)

        self.Menu.add(self.menu_Acerca_de)

        





        self.setJMenuBar(self.Menu)
        self.setBounds(0, 0, 1095, 670)
        
######################################    
    def integrantes(self,event):
        informacion()
    def cortar(self,event): 
        self.txtArea_Principal.cut()    
    def copiar(self,event): 
        self.txtArea_Principal.copy()
    def pegar(self,event): 
        self.txtArea_Principal.paste()
    def salir(self,event): 
        self.dispose()
######################################    



    def guardarcomo(self,event): pass
    def guardar(self,event):
        if self.ruta == "":
            self.txtTerminal.setText("no hay un directorio abierto")
        else:
            agregar(self.ruta,str(self.txtArea_Principal.getText()))

    def cerrar(self,event): 
        self.txtArea_Principal.setText("")
        self.txtArea_Principal.setEnabled(False)
        
        self.ruta=""
        

    
    def abrir(self,event):   
        self.jf.showOpenDialog(self)
        self.ruta = self.jf.getSelectedFile()    
        self.txtArea_Principal.setEnabled(True)
        self.txtArea_Principal.setText(abrir(self.ruta)) 




    def nuevo(self,event):
        if self.ruta == "":
            print("no pasa nada")
        else:
            print("hay un archivo existente")
            self.ruta =""
            
        self.txtArea_Principal.setEnabled(True)
        self.txtArea_Principal.setText("")
######################################    
    def lexico(self,event):
        self.txtTerminal.setText("")
        archivo = open("{}".format(self.ruta),"r")
        texto = ""
        for a in prueba(self.txtArea_Principal.getText()):
            texto += a+"\n"
        
        self.txtTerminal.setText(texto)


    def sintactico(self,event):
        self.txtTerminal.setText("")
        texto=""
        for a in prueba_sintactica(self.txtArea_Principal.getText()):
            texto +=a+"\n"

        self.txtTerminal.setText(texto)
class gui(JFrame):
    def __init__(self):

        #Class variable declarations
        self.mainPanel = JPanel(GridLayout(1, 2))
        self.subPanel1 = JPanel(BorderLayout())
        self.subPanel2 = JPanel(GridLayout(5, 1))

        self.userText = JTextArea(' ')

        self.emoticonFeedback = JTextArea(
            'This will consider your emoticon usage.')
        self.curseFeedback = JTextArea(
            'This will consider your use of profanity.')
        self.styleFeedback = JTextArea('This will consider your general tone.')
        self.overallFeedback = JTextArea('This will be your overall score.')

        self.button = JButton("Score my email!",
                              actionPerformed=self.updateScores)

        self.initGUI()
        self.add(self.mainPanel)

        self.setSize(800, 500)
        self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
        self.setVisible(True)

    def initGUI(self):
        #Set up subpanel1
        appName = JTextArea('Politeness Gauge\n' +
                            '\nSarah Robinson \nAnna Clegg')
        appName.setLineWrap(True)
        appName.setWrapStyleWord(True)
        appName.setEditable(False)
        appName.background = 240, 240, 240
        instructions = JTextArea(
            '   Ever agonized over whether or not your emails' +
            ' are polite enough? \n    Never fear! With our politeness gauge' +
            ' we can provide suggestions on improving your emails' +
            ' with just the click of a button.  \n    Just type your email ' +
            'into the text box below and hit Score!')
        instructions.setLineWrap(True)
        instructions.setWrapStyleWord(True)
        instructions.background = 240, 240, 240
        northPanel = JPanel(GridLayout(2, 1))
        northPanel.add(appName)
        northPanel.add(instructions)
        self.subPanel1.add(northPanel, BorderLayout.NORTH)

        self.userText.setEditable(True)
        self.userText.setLineWrap(True)
        self.userText.setWrapStyleWord(True)
        self.userText.setRows(100)
        #self.userText.wordWrap = True
        self.subPanel1.add(self.userText, BorderLayout.CENTER)

        self.subPanel1.add(self.button, BorderLayout.SOUTH)

        label = JLabel("Politeness Evaluation")
        self.subPanel2.add(label)
        self.subPanel2.add(self.emoticonFeedback)
        self.subPanel2.add(self.curseFeedback)
        self.subPanel2.add(self.styleFeedback)
        self.subPanel2.add(self.overallFeedback)

        self.mainPanel.add(self.subPanel1)
        self.mainPanel.add(self.subPanel2)

    def updateScores(self, event):
        input = self.userText.getText()
        scores = mes.get_scores(input)
        overall = mes.get_overall_score()

        self.styleFeedback.setText(
            "\n Your politeness score is " + str(scores['politeness']) +
            ".\n Higher is better. This is relative to the\n length of your email,"
            +
            " so the more sentences you have,\n the higher this score should be."
        )

        self.curseFeedback.setText(" You have about " + str(scores['curses']) +
                                   " curses in you email." +
                                   "\n Please try to have 0 curses.")
        self.emoticonFeedback.setText(
            " You have about " + str(scores['emoticons']) +
            " emoticons in your email." +
            "\n Fewer emoticons is considered more professional.")

        self.overallFeedback.setText(
            " Your overall professionality score is " + str(overall) + "." +
            "\n The baseline is around 50 for neutral emails." +
            "\n Please remember that this is approximate.")
Esempio n. 18
0
class MyPanel(JSplitPane):

    def __init__(self, scannerInstance):
        self.scannerInstance = scannerInstance
        JSplitPane.__init__(self, JSplitPane.VERTICAL_SPLIT)
        # super(MyPanel, self).__init__(self, JSplitPane.VERTICAL_SPLIT)
        # self.setSize(640, 460)
        self.setBorder(EmptyBorder(20, 20, 20, 20))

        self.topPanel = JPanel(BorderLayout(10, 10))
        self.topPanel.setBorder(EmptyBorder(0, 0, 10, 0))
        # self.topPanel.setBackground(Color.blue)

        self.bottomPanel = JPanel()
        self.bottomPanel.setBorder(EmptyBorder(10, 0, 0, 0))
        # self.bottomPanel.setBackground(Color.yellow)

        self.bottomPanel.setPreferredSize(Dimension(580, 40))
        # plain
        self.plainPanel = JPanel(BorderLayout(10, 10))

        self.plainTextPane = JTextArea()
        self.plainTextPane.setLineWrap(True)
        self.plainTextPane.setEditable(True)

        self.plainScrollPane = JScrollPane(self.plainTextPane)
        self.plainScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)

        self.plainPanel.add(JLabel("PLAIN:", SwingConstants.CENTER), BorderLayout.PAGE_START)
        self.plainPanel.add(self.plainScrollPane, BorderLayout.CENTER)

        self.topPanel.add(self.plainPanel, BorderLayout.LINE_START)

        # button
        self.btnsPanel = JPanel(GridBagLayout())
        gbc = GridBagConstraints()

        gbc.fill = GridBagConstraints.HORIZONTAL
        gbc.gridx = 0
        gbc.gridy = 0
        self.btnsPanel.add(JButton("=Encrypt=>", actionPerformed=self.encrypt), gbc)


        gbc.fill = GridBagConstraints.HORIZONTAL
        gbc.gridx = 0
        gbc.gridy = 1
        self.btnsPanel.add(JButton("<=Decrypt=", actionPerformed=self.decrypt), gbc)

        gbc.fill = GridBagConstraints.HORIZONTAL
        gbc.gridx = 0
        gbc.gridy = 2
        gbc.gridheight = 2
        gbc.ipadx = 10
        self.btnsPanel.add(JButton("SIGN", actionPerformed=self.sign), gbc)

        # b_enc.setPreferredSize(Dimension(30, 20))
        # b_dec.setPreferredSize(Dimension(30, 20))

        self.topPanel.add(self.btnsPanel, BorderLayout.CENTER)

        # cipher
        self.cipherPanel = JPanel(BorderLayout(10, 10))

        self.cipherTextPane = JTextArea()
        self.cipherTextPane.setLineWrap(True)
        self.cipherTextPane.setEditable(True)

        self.cipherScrollPane = JScrollPane(self.cipherTextPane)
        self.cipherScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)

        self.cipherPanel.add(JLabel("CIPHER:", SwingConstants.CENTER), BorderLayout.PAGE_START)
        self.cipherPanel.add(self.cipherScrollPane, BorderLayout.CENTER)

        self.topPanel.add(self.cipherPanel, BorderLayout.LINE_END)

        self.signPanel = JPanel(FlowLayout(FlowLayout.LEADING, 10, 10))
        self.signPanel.add(JLabel("SIGN:", SwingConstants.LEFT), BorderLayout.LINE_START)
        self.signField = JTextField(50)
        self.signPanel.add(self.signField)

        self.bottomPanel.add(self.signPanel)

        self.plainPanel.setPreferredSize(Dimension(260, 400))
        self.btnsPanel.setPreferredSize(Dimension(80, 400))
        self.cipherPanel.setPreferredSize(Dimension(260, 400))

        self.setTopComponent(self.topPanel)
        self.setBottomComponent(self.bottomPanel)


    def setPlain(self, plain):
        if plain:
            self.plainTextPane.setText(plain.decode("utf-8"))

    def setCipher(self, cipher):
        self.cipherTextPane.setText(cipher)

    def setSignature(self, sign):
        self.signField.setText(sign)

    def unicode_to_str(self, content):
        data = ""
        for i in content:
            data += chr(ord(i))
        return data


    def get_real_content(self, content):
        s_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        handled_cnt = None
        data = self.unicode_to_str(content)
        try:
            s_client.connect(LOCAL_IPC)
            s_client.send(data)
            handled_cnt = ""

            while True:
                _sp = s_client.recv(1024)
                if _sp and len(_sp) > 0:
                    handled_cnt += _sp

                    if len(_sp) < 1024:
                        break
                else:
                    break

        except socket.error:
            BP_STDERR.println("fail to connect local IPC service.")

        s_client.close()
        # BP_STDOUT.println("get_real_content - %s" % handled_cnt.decode("utf-8"))
        return handled_cnt if handled_cnt and len(handled_cnt) > 0 else None


    def encrypt(self, event):
        plain = self.plainTextPane.getText()
        # BP_STDERR.println("plain type - %s" % type(plain))
        result = self.get_real_content(b"\x01" + plain)
        self.setCipher(result)


    def decrypt(self, event, is_req=None):
        cipher = self.cipherTextPane.getText()
        # BP_STDERR.println("cipher type - %s" % type(cipher))
        flag = b"\x02" if is_req is True else b"\x03" if is_req is False else b"\x00"
        result = self.get_real_content(flag + cipher)
        self.setPlain(result)


    def sign(self, event):
        text = self.plainTextPane.getText()
        # BP_STDERR.println("sign func called! - %s" % text)
        result = self.get_real_content(b"\x04" + text)
        self.setSignature(result)
Esempio n. 19
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()
Esempio n. 20
0
class BurpExtender(IBurpExtender, ITab, IHttpListener, IContextMenuFactory, IMessageEditorController, AbstractTableModel):

    #
    # implement IBurpExtender
    #

    def registerExtenderCallbacks(self, callbacks):
        print("[*] Loading Jaeles beta v0.1")
        # keep a reference to our callbacks object
        self._callbacks = callbacks

        # obtain an extension helpers object
        self._helpers = callbacks.getHelpers()

        # set our extension name
        callbacks.setExtensionName("Jaeles")

        # main split pane
        self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT)

        # table of log entries
        # logTable = Table(self)
        # scrollPane = JScrollPane(logTable)

        # _toppane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT)
        _mainpane = JSplitPane(JSplitPane.VERTICAL_SPLIT)
        _mainpane.setResizeWeight(0.5)
        # _mainpane = JPanel()

        _toppane = JPanel()

        # top pane
        self.banner = JLabel("Jaeles - The Swiss Army knife for automated Web Application Testing. ")
        self.banner.setBounds(50, 30, 200, 400)

        self.banner2 = JLabel("Official Documentation: https://jaeles-project.github.io/")
        self.banner2.setBounds(100, 50, 200, 400)
        _toppane.add(self.banner)
        _toppane.add(self.banner2)

        # _botpane = JPanel()
        _botpane = JSplitPane(JSplitPane.VERTICAL_SPLIT)

        # bot pane
        self.HostLabel = JLabel("Jaeles Endpoint: ")
        self.HostLabel.setBounds(100, 150, 200, 400)

        self.Jaeles_endpoint = 'http://127.0.0.1:5000/api/parse'
        self.jwt = 'Jaeles token_here'
        # just prevent plugin error when you doesn't have server running
        try:
            self.initial()
            jwt, endpoint = self.get_config()
            if endpoint:
                self.Jaeles_endpoint = endpoint        
            if jwt:
                self.jwt = jwt
        except:
            pass

        endpoint_pane = JPanel()

        # end point to submit request
        self.EndpointText = JTextArea(self.Jaeles_endpoint, 3, 100)

        self.jwtLabel = JLabel("Jaeles JWT token: ")
        self.jwtLabel.setBounds(100, 300, 250, 450)

        self.jwtText = JTextArea(self.jwt, 3, 100, lineWrap=True)

        buttons = JPanel()
        self.buttonLabel = JLabel("Actions: ")
        self.buttonLabel.setBounds(150, 200, 200, 400)
        self._saveButton = JButton("Save", actionPerformed=self.saveToken)
        self._loadButton = JButton(
            "Test Connection", actionPerformed=self.butClick)
        self._reloadButton = JButton("Reload", actionPerformed=self.butClick)

        oob_control = JPanel()
        self.oobLabel = JLabel("OOB: ")
        self.oobLabel.setBounds(150, 200, 200, 400)
        self._saveoob = JButton("Save OOB", actionPerformed=self.saveToken)
        self._pollingBox = JCheckBox("Polling")
        self._pollingBox.setBounds(290, 25, 300, 30)
        oob_control.add(self.oobLabel)
        oob_control.add(self._saveoob)
        oob_control.add(self._pollingBox)

        # _botpane.add(self.banner)
        # endpoint_pane.add(self.blankLabel)
        endpoint_pane.add(self.HostLabel)
        endpoint_pane.add(self.EndpointText)
        endpoint_pane.add(self.jwtLabel)
        endpoint_pane.add(self.jwtText)

        buttons.add(self.buttonLabel)
        buttons.add(self._saveButton)
        buttons.add(self._loadButton)
        buttons.add(self._reloadButton)

        _botpane.setLeftComponent(oob_control)
        _botpane.setLeftComponent(endpoint_pane)
        _botpane.setRightComponent(buttons)
        _botpane.setResizeWeight(0.7)

        # set
        _mainpane.setLeftComponent(_toppane)
        _mainpane.setRightComponent(_botpane)

        self._splitpane.setLeftComponent(_mainpane)

        ###########
        # tabs with request/response viewers
        tabs = JTabbedPane()

        self.log_area = JTextArea("", 5, 30)
        # self._requestViewer = callbacks.createMessageEditor(self, False)

        tabs.addTab("Log", self.log_area)
        # tabs.addTab("Config", self._requestViewer.getComponent())

        self._splitpane.setRightComponent(tabs)
        self._splitpane.setResizeWeight(0.5)

        callbacks.customizeUiComponent(self._splitpane)
        callbacks.customizeUiComponent(tabs)

        callbacks.registerContextMenuFactory(self)

        # add the custom tab to Burp's UI
        callbacks.addSuiteTab(self)

        # register ourselves as an HTTP listener
        # callbacks.registerHttpListener(self)
        self.print_log("[*] Jaeles Loaded ...")
        return

    #
    # implement ITab
    #

    ##
    def saveToken(self, e):
        token = self.jwtText.getText().strip()
        endpoint = self.EndpointText.getText().strip()
        self.Jaeles_endpoint = endpoint
        self.jwt = token
        self.set_config(token, endpoint)

    def butClick(self, e):
        button_name = e.getActionCommand()

        if button_name == 'Reload':
            # self.initial()
            username, password = self.get_cred()
            self.login(username, password)
            jwt, endpoint = self.get_config()
            self.Jaeles_endpoint = endpoint
            self.jwt = jwt
            self.print_log("[+] Reload Config")

        elif button_name == 'Test Connection':
            connection = self.test_connection()
            if connection:
                self.print_log("[+] Ready to send request to {0}".format(self.Jaeles_endpoint))
            else:
                self.print_log("[-] Fail to authen with API server at {0}".format(self.Jaeles_endpoint))

    def createMenuItems(self, invocation):
        responses = invocation.getSelectedMessages()
        if responses > 0:
            ret = LinkedList()
            requestMenuItem = JMenuItem("[*] Send request to Jaeles Endpoint")
            requestMenuItem.addActionListener(
                handleMenuItems(self, responses, "request"))
            ret.add(requestMenuItem)
            return ret
        return None

    def highlightTab(self):
        currentPane = self._splitpane
        previousPane = currentPane
        while currentPane and not isinstance(currentPane, JTabbedPane):
            previousPane = currentPane
            currentPane = currentPane.getParent()
        if currentPane:
            index = currentPane.indexOfComponent(previousPane)
            currentPane.setBackgroundAt(index, Color(0xff6633))

            class setColorBackActionListener(ActionListener):
                def actionPerformed(self, e):
                    currentPane.setBackgroundAt(index, Color.BLACK)

            timer = Timer(5000, setColorBackActionListener())
            timer.setRepeats(False)
            timer.start()

    def getTabCaption(self):
        return "Jaeles"

    def getUiComponent(self):
        return self._splitpane

    #
    # implement Polling Collaborator
    # this allows our request/response viewers to obtain details about the messages being displayed
    #
    # def jaeles_collab(self, collab):
    #     oob = collab.generatePayload(True)

    #     # oob2 = collab.generatePayload(True)
    #     # print(oob2)
    #     self.print_log("[+] Gen oob host: {0}".format(oob))
    #     # print(oob)
    #     # os.system('curl {0}'.format(oob))

    #
    # implement IMessageEditorController
    # this allows our request/response viewers to obtain details about the messages being displayed
    #
    def sendRequestToJaeles(self, messageInfos):
        for messageInfo in messageInfos:
            data_json = self.req_parsing(messageInfo)

            if data_json:
                self.print_log("Import to external Jaeles ...")
                self.import_to_Jaeles(data_json)
            else:
                self.print_log("No response on selected request")
            self.print_log("-"*30)

    # start of my function
    def req_parsing(self, messageInfo):
        data_json = {}
        data_json['req_scheme'] = str(messageInfo.getProtocol())  # return http
        data_json['req_host'] = str(messageInfo.getHost())
        data_json['req_port'] = str(messageInfo.getPort())
        data_json['url'] = str(messageInfo.getUrl())

        # full request
        full_req = self._helpers.bytesToString(messageInfo.getRequest())
        data_json['req'] = self.just_base64(str(full_req))

        if messageInfo.getResponse():
            full_res = self._helpers.bytesToString(messageInfo.getResponse())
        else:
            full_res = None
        if not full_res:
            data_json['res'] = ""
            return data_json

        data_json['res'] = self.just_base64(str(full_res.encode('utf-8')))
        return data_json

    # send data to Jaeles API Endpoint
    def import_to_Jaeles(self, data_json):
        req = urllib2.Request(self.Jaeles_endpoint)
        req.add_header('Content-Type', 'application/json')
        req.add_header('Authorization', self.jwt)
        response = urllib2.urlopen(req, json.dumps(data_json))
        if str(response.code) == "200":
            self.print_log("[+] Start scan {0}".format(data_json['url']))
        else:
            self.print_log("[-] Fail Send request to {0}".format(self.Jaeles_endpoint))

    # check if token is available or not
    def initial(self):
        connection = self.test_connection()
        if connection:
            return True
        username, password = self.get_cred()
        valid_cred = self.login(username, password)
        if valid_cred:
            return True
        return False

    # do login
    def login(self, username, password):
        req = urllib2.Request(self.Jaeles_endpoint.replace("/api/parse","/auth/login"))
        req.add_header('Content-Type', 'application/json')
        response = urllib2.urlopen(req, json.dumps({"username": username, "password": password}))

        if str(response.code) == "200":
            data = json.loads(response.read())
            token = "Jaeles " + data.get("token")
            self.set_config(token, self.Jaeles_endpoint, username, password)
            print("[+] Authentication success on {0}".format(self.Jaeles_endpoint))
            return True
        else:
            print("[-] Can't authen on {0}".format(self.Jaeles_endpoint))
            return False

    # check connection
    def test_connection(self):
        req = urllib2.Request(self.Jaeles_endpoint.replace("/parse", "/ping"))
        req.add_header('Content-Type', 'application/json')
        req.add_header('Authorization', self.jwt)
        try:
            response = urllib2.urlopen(req)
            if str(response.code) == "200":
                return True
        except:
            pass
        return False

    # get default credentials
    def get_cred(self):
        config_path = self.get_config_path()
        if os.path.isfile(config_path):
            with open(config_path, 'r') as f:
                data = json.load(f)
            print('[+] Load credentials from {0}'.format(config_path))
            return data.get('username', False), data.get('password', False)
        else:
            print('[-] No config file to load.')
            return False, False

    # get token and endpoint
    def get_config(self):
        config_path = self.get_config_path()
        if os.path.isfile(config_path):
            with open(config_path, 'r') as f:
                data = json.load(f)
            print('[+] Load JWT from {0}'.format(config_path))
            return data.get('JWT', False), data.get('endpoint', False)
        else:
            print('[-] No config file to load.')
            return False, False

    # save jwt token and endpoint to ~/.jaeles/burp.json
    def set_config(self, token, endpoint, username='', password=''):
        data = {
            'JWT': token,
            'endpoint': endpoint,
            'username': username,
            'password': password,
        }
        config_path = self.get_config_path()
        jaeles_path = os.path.dirname(config_path)

        if jaeles_path and not os.path.exists(jaeles_path):
            os.makedirs(jaeles_path)
        with open(config_path, 'w+') as f:
            json.dump(data, f)

        print('[+] Store JWT in {0}'.format(config_path))
        return True

    def just_base64(self, text):
        if not text:
            return ""
        return str(base64.b64encode(str(text)))

    def get_config_path(self):
        home = os.path.expanduser('~{0}'.format(getpass.getuser()))
        jaeles_path = os.path.join(home, '.jaeles')

        config_path = os.path.join(jaeles_path, 'burp.json')
        return config_path

    def print_log(self, text):
        if type(text) != str:
            text = str(text)
        self.log_area.append(text)
        self.log_area.append("\n")

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

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

    def getResponse(self):
        return self._currentlyDisplayedItem.getResponse()
Esempio n. 21
0
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel):
    
    #
    # implement IBurpExtender
    #
    
    def	registerExtenderCallbacks(self, callbacks):
    
        # keep a reference to our callbacks object
        self._callbacks = callbacks
        
        # obtain an extension helpers object
        self._helpers = callbacks.getHelpers()
        
        # set our extension name
        callbacks.setExtensionName("Otter")
        
        # create the log and a lock on which to synchronize when adding log entries
        self._log = ArrayList()
        self._lock = Lock()
       
        # main split pane for log entries and request/response viewing
        self._settingPanel = JPanel()
        self._logPane = JSplitPane(JSplitPane.VERTICAL_SPLIT)

        # setup settings pane ui
        self._settingPanel.setBounds(0,0,1000,1000)
        self._settingPanel.setLayout(None)

        self._isRegexp = JCheckBox("Use regexp for matching.")
        self._isRegexp.setBounds(10, 10, 220, 20)

        matchLabel = JLabel("String to Match:")
        matchLabel.setBounds(10, 40, 200, 20)
        self._matchString = JTextArea("User 1 Session Information")
        self._matchString.setWrapStyleWord(True)
        self._matchString.setLineWrap(True)
        matchString = JScrollPane(self._matchString)
        matchString.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        matchString.setBounds(10, 60, 400, 200)

        replaceLabel = JLabel("String to Replace:")
        replaceLabel.setBounds(10, 270, 200, 20)
        self._replaceString = JTextArea("User 2 Session Information")
        self._replaceString.setWrapStyleWord(True)
        self._replaceString.setLineWrap(True)
        replaceString = JScrollPane(self._replaceString)
        replaceString.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        replaceString.setBounds(10, 290, 400, 200)

        self._settingPanel.add(self._isRegexp)
        self._settingPanel.add(matchLabel)
        self._settingPanel.add(matchString)
        self._settingPanel.add(replaceLabel)
        self._settingPanel.add(replaceString)
        
        # table of log entries
        logTable = Table(self)
        logTable.getColumnModel().getColumn(0).setPreferredWidth(700)
        logTable.getColumnModel().getColumn(1).setPreferredWidth(150)
        logTable.getColumnModel().getColumn(2).setPreferredWidth(100)
        logTable.getColumnModel().getColumn(3).setPreferredWidth(130)
        logTable.getColumnModel().getColumn(4).setPreferredWidth(100)
        logTable.getColumnModel().getColumn(5).setPreferredWidth(130)
        scrollPane = JScrollPane(logTable)
        self._logPane.setLeftComponent(scrollPane)

        # tabs with request/response viewers
        logTabs = JTabbedPane()
        self._origRequestViewer = callbacks.createMessageEditor(self, False)
        self._origResponseViewer = callbacks.createMessageEditor(self, False)
        self._modRequestViewer = callbacks.createMessageEditor(self, False)
        self._modResponseViewer = callbacks.createMessageEditor(self, False)
        logTabs.addTab("Original Request", self._origRequestViewer.getComponent())
        logTabs.addTab("Original Response", self._origResponseViewer.getComponent())
        logTabs.addTab("Modified Request", self._modRequestViewer.getComponent())
        logTabs.addTab("Modified Response", self._modResponseViewer.getComponent())
        self._logPane.setRightComponent(logTabs)
        
        # top most tab interface that seperates log entries from settings
        maintabs = JTabbedPane()
        maintabs.addTab("Log Entries", self._logPane)
        maintabs.addTab("Settings", self._settingPanel)
        self._maintabs = maintabs
       
        # customize the UI components
        callbacks.customizeUiComponent(maintabs)
        
        # add the custom tab to Burp's UI
        callbacks.addSuiteTab(self)
        
        # register ourselves as an HTTP listener
        callbacks.registerHttpListener(self)
        
        return
        
    #
    # implement ITab
    #
    
    def getTabCaption(self):
        return "Otter"
    
    def getUiComponent(self):
        return self._maintabs
        
    #
    # implement IHttpListener
    #
    
    def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
   
        # Only process responses that came from the proxy. This will
        # ignore request/responses made by Otter itself.
        if not messageIsRequest and toolFlag == self._callbacks.TOOL_PROXY:
            # create a new log entry with the message details
            row = self._log.size()

            # analyze and store information about the original request/response
            responseBytes = messageInfo.getResponse()
            requestBytes = messageInfo.getRequest()
            request = self._helpers.analyzeRequest(messageInfo)
            response = self._helpers.analyzeResponse(responseBytes)
            
            # ignore out-of-scope requests.
            if not self._callbacks.isInScope(request.getUrl()):
                return

            wasModified = False
            ms = self._matchString.getText()
            rs = self._replaceString.getText()
            mss = ms.split(",")
            rss = rs.split(",")
            if len(rss) != len(mss):
                mss = [""]
                
            for i,x in enumerate(mss):
                if x == "":
                    continue
                if self._isRegexp.isSelected():
                    if search(x, requestBytes):
                        requestBytes = sub(x, rss[i], requestBytes)
                        wasModified = True
                else:
                    if fromBytes(requestBytes).find(x) >= 0:
                        requestBytes = toBytes(replace(fromBytes(requestBytes), x, rss[i]))
                        wasModified = True

            # make a modified request to test for authorization issues
            entry = None
            if wasModified:
                modReqResp = self._callbacks.makeHttpRequest(messageInfo.getHttpService(), requestBytes)
                modRequestBytes = modReqResp.getRequest()
                modResponseBytes = modReqResp.getResponse()
                modResponse = self._helpers.analyzeResponse(modResponseBytes)
                orig = self._callbacks.saveBuffersToTempFiles(messageInfo)
                mod = self._callbacks.saveBuffersToTempFiles(modReqResp)
                entry = LogEntry(orig, mod, request.getUrl(), response.getStatusCode(), len(responseBytes), modResponse.getStatusCode(), len(modResponseBytes), wasModified)
            else:
                orig = self._callbacks.saveBuffersToTempFiles(messageInfo)
                entry = LogEntry(orig, None, request.getUrl(), response.getStatusCode(), len(responseBytes), "None", 0, wasModified)

            self._lock.acquire()
            self._log.add(entry)
            self.fireTableRowsInserted(row, row)
            self._lock.release()
        return

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

    def getColumnCount(self):
        return 6

    def getColumnName(self, columnIndex):
        if columnIndex == 0:
            return "URL"
        if columnIndex == 1:
            return "Request Modified?"
        if columnIndex == 2:
            return "Orig. Status"
        if columnIndex == 3:
            return "Orig. Length"
        if columnIndex == 4:
            return "Mod. Status"
        if columnIndex == 5:
            return "Mod. Length"
        return ""

    def getValueAt(self, rowIndex, columnIndex):
        logEntry = self._log.get(rowIndex)
        if columnIndex == 0:
            return logEntry._url.toString()
        if columnIndex == 1:
            return str(logEntry._wasModified)
        if columnIndex == 2:
            return str(logEntry._origStatus)
        if columnIndex == 3:
            return str(logEntry._origLength)
        if columnIndex == 4:
            return str(logEntry._modStatus)
        if columnIndex == 5:
            return str(logEntry._modLength)
        return ""

    #
    # implement IMessageEditorController
    # this allows our request/response viewers to obtain details about the messages being displayed
    #
    
    def getHttpService(self):
        return self._currentlyDisplayedItem.getHttpService()

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

    def getResponse(self):
        return self._currentlyDisplayedItem.getResponse()
Esempio n. 22
0
class BurpExtender(IBurpExtender, ITab):
    def registerExtenderCallbacks(self, callbacks):
        print "JSON&HTTPP by [Vulkey_Chen]\nBlog: gh0st.cn\nTeam: MSTSEC"
        self._cb = callbacks
        self._hp = callbacks.getHelpers()
        self._cb.setExtensionName("JSON&HTTPP")
        self.mainPanel = JPanel()
        self.mainPanel.setLayout(BorderLayout())

        self.jsonTextArea = JTextArea(20, 0)
        self.jsonTextArea.setLineWrap(True)

        self.dictTextArea = JTextArea()
        self.dictTextArea.setLineWrap(True)

        self.keyTextArea = JTextArea()
        self.keyTextArea.setLineWrap(True)

        self.valueTextArea = JTextArea()
        self.valueTextArea.setLineWrap(True)

        self.resultPanel = JPanel()
        # self.resultPanel.setLayout(BorderLayout())
        self.resultPanel.layout = GridLayout(1, 3)

        self.jsonTextWrapper = JPanel()
        self.jsonTextWrapper.setLayout(BorderLayout())
        self.jsonTextWrapper.border = BorderFactory.createTitledBorder("Input")
        self.dictTextWrapper = JPanel()
        self.dictTextWrapper.setLayout(BorderLayout())
        self.dictTextWrapper.border = BorderFactory.createTitledBorder(
            "Output")
        self.keyTextWrapper = JPanel()
        self.keyTextWrapper.setLayout(BorderLayout())
        self.keyTextWrapper.border = BorderFactory.createTitledBorder("Keys")
        self.valueTextWrapper = JPanel()
        self.valueTextWrapper.setLayout(BorderLayout())
        self.valueTextWrapper.border = BorderFactory.createTitledBorder(
            "Values")

        self.jsonScrollPane = JScrollPane(self.jsonTextArea)
        self.dictScrollPane = JScrollPane(self.dictTextArea)
        self.valueScrollPane = JScrollPane(self.valueTextArea)
        self.keyScrollPane = JScrollPane(self.keyTextArea)

        self.jsonTextWrapper.add(self.jsonScrollPane, BorderLayout.CENTER)
        self.dictTextWrapper.add(self.dictScrollPane, BorderLayout.CENTER)
        self.keyTextWrapper.add(self.keyScrollPane, BorderLayout.CENTER)
        self.valueTextWrapper.add(self.valueScrollPane, BorderLayout.CENTER)

        self.resultPanel.add(self.dictTextWrapper, BorderLayout.WEST)
        self.resultPanel.add(self.keyTextWrapper, BorderLayout.CENTER)
        self.resultPanel.add(self.valueTextWrapper, BorderLayout.EAST)

        self.mainPanel.add(self.jsonTextWrapper, BorderLayout.NORTH)
        self.mainPanel.add(self.resultPanel, BorderLayout.CENTER)

        self.beautifyButton_1 = JButton("JSON2HTTPP",
                                        actionPerformed=self.onClick1)
        self.beautifyButton_2 = JButton("HTTPP2JSON",
                                        actionPerformed=self.onClick2)
        self.clearButton = JButton("CLEAR", actionPerformed=self.onClear)

        self.buttons = JPanel()
        self.buttons.add(self.beautifyButton_1, BorderLayout.CENTER)
        self.buttons.add(self.beautifyButton_2, BorderLayout.CENTER)
        self.buttons.add(self.clearButton, BorderLayout.CENTER)

        self.mainPanel.add(self.buttons, BorderLayout.SOUTH)

        self._cb.customizeUiComponent(self.mainPanel)
        self._cb.addSuiteTab(self)

    def onClick1(self, event):
        _jsontext = self.jsonTextArea.getText().strip()
        try:
            _jsontext = json.loads(
                re.search(r"\({.*?}\)",
                          _jsontext).group().replace("(", "").replace(")", ""))
        except:
            _jsontext = json.loads(_jsontext)
        self._result = []
        # resultDict format: ["aa=bb","cc=ddd"]
        resultDict = self.json2dict(_jsontext)
        self.dictTextArea.append("\n".join(resultDict))
        keyList = set()
        valueList = set()
        for result in resultDict:
            key, value = result.split("=")[0], result.split("=")[1]
            if len(key) > 0:
                keyList.add(key)
            if len(value) > 0:
                valueList.add(value)
        self.keyTextArea.append("\n".join(keyList))
        self.valueTextArea.append("\n".join(valueList))

        self.dictTextArea.append("\n")
        self.keyTextArea.append("\n")
        self.valueTextArea.append("\n")

    def onClick2(self, event):
        _jsontext = self.jsonTextArea.getText().strip()
        _res = []
        keyList = set()
        valueList = set()
        for i in _jsontext.split("&"):
            args = i.split("=")
            for x in args:
                _res.append(x)
            if len(args[0]) > 0:
                keyList.add(args[0])
            if len(args[1]) > 0:
                valueList.add(args[1])
        self.dictTextArea.append(json.dumps(dict(zip(_res[0::2], _res[1::2]))))
        self.keyTextArea.append("\n".join(keyList))
        self.valueTextArea.append("\n".join(valueList))

        self.dictTextArea.append("\n")
        self.keyTextArea.append("\n")
        self.valueTextArea.append("\n")

    def onClear(self, event):
        self.dictTextArea.setText("")
        self.keyTextArea.setText("")
        self.valueTextArea.setText("")

    def json2dict(self, _jsontext):
        keyValue = ""
        if isinstance(_jsontext, dict):
            for key in _jsontext.keys():
                keyValue = _jsontext.get(key)
                if isinstance(keyValue, dict):
                    self.json2dict(keyValue)
                elif isinstance(keyValue, list):
                    for json_array in keyValue:
                        self.json2dict(json_array)
                else:
                    if type(keyValue) is int or type(keyValue) == long or type(
                            keyValue) == str:
                        self._result.append(str(key) + "=" + str(keyValue))
                    elif type(keyValue) is bool:
                        self._result.append(
                            str(key) + "=" + str(int(keyValue)))
                    elif type(keyValue) == type(None):
                        self._result.append(str(key) + "=" + "")
                    else:
                        self._result.append(str(key) + "=" + keyValue)
        elif isinstance(_jsontext, list):
            for _jsontext_array in _jsontext:
                self.json2dict(_jsontext_array)
        return self._result

    def getTabCaption(self):
        return "JSON&HTTPP"

    def getUiComponent(self):
        return self.mainPanel
Esempio n. 23
0
class BurpExtender(IBurpExtender, ITab, IHttpListener,
                   IMessageEditorController, AbstractTableModel,
                   IContextMenuFactory, IExtensionStateListener):

    #
    # implement IBurpExtender
    #

    def registerExtenderCallbacks(self, callbacks):
        # keep a reference to our callbacks object
        self._callbacks = callbacks

        # obtain an extension helpers object
        self._helpers = callbacks.getHelpers()

        # set our extension name
        callbacks.setExtensionName("Burp Scope Monitor Experimental")

        self.GLOBAL_HANDLER_ANALYZED = False
        self.GLOBAL_HANDLER = False
        self.STATUS = False
        self.AUTOSAVE_REQUESTS = 10
        self.AUTOSAVE_TIMEOUT = 600  # 10 minutes should be fine
        self.CONFIG_INSCOPE = True

        self.BAD_EXTENSIONS_DEFAULT = [
            '.gif', '.png', '.js', '.woff', '.woff2', '.jpeg', '.jpg', '.css',
            '.ico', '.m3u8', '.ts', '.svg'
        ]
        self.BAD_MIMES_DEFAULT = [
            'gif', 'script', 'jpeg', 'jpg', 'png', 'video', 'mp2t'
        ]

        self.BAD_EXTENSIONS = self.BAD_EXTENSIONS_DEFAULT
        self.BAD_MIMES = self.BAD_MIMES_DEFAULT

        # create the log and a lock on which to synchronize when adding log entries

        self._currentlyDisplayedItem = None

        self.SELECTED_MODEL_ROW = 0
        self.SELECTED_VIEW_ROW = 0

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

        # main split pane
        self._parentPane = JTabbedPane()

        self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT)

        ##### config pane
        self._config = JTabbedPane()

        config = JPanel()
        iexport = JPanel()

        #config.setLayout(BorderLayout())
        config.setLayout(None)
        iexport.setLayout(None)

        # config radio button
        X_BASE = 40
        Y_OFFSET = 5
        Y_OPTION = 200
        Y_OPTION_SPACING = 20
        Y_CHECKMARK_SPACING = 20

        self.showAllButton = JRadioButton(SHOW_ALL_BUTTON_LABEL, True)
        self.showNewButton = JRadioButton(SHOW_NEW_BUTTON_LABEL, False)
        self.showTestedButton = JRadioButton(SHOW_TEST_BUTTON_LABEL, False)

        self.showAllButton.setBounds(40, 60 + Y_OFFSET, 400, 30)
        self.showNewButton.setBounds(40, 80 + Y_OFFSET, 400, 30)
        self.showTestedButton.setBounds(40, 100 + Y_OFFSET, 400, 30)
        #self.showNewButton = JRadioButton(SHOW_NEW_BUTTON_LABEL, False)
        #self.showTestedButton = JRadioButton(SHOW_TEST_BUTTON_LABEL, False)

        self.showAllButton.addActionListener(self.handleRadioConfig)
        self.showNewButton.addActionListener(self.handleRadioConfig)
        self.showTestedButton.addActionListener(self.handleRadioConfig)

        self.clearButton = JButton("Clear")
        self.clearButton.addActionListener(self.handleClearButton)
        self.clearButton.setBounds(40, 20, 100, 30)

        self.startButton = JButton(MONITOR_ON_LABEL)
        self.startButton.addActionListener(self.handleStartButton)
        self.startButton.setBounds(150, 20, 200, 30)

        self.badExtensionsLabel = JLabel("Ignore extensions:")
        self.badExtensionsLabel.setBounds(X_BASE, 150, 200, 30)

        self.badExtensionsText = JTextArea("")
        self.loadBadExtensions()
        self.badExtensionsText.setBounds(X_BASE, 175, 310, 30)

        self.badExtensionsButton = JButton("Save")
        self.badExtensionsButton.addActionListener(
            self.handleBadExtensionsButton)
        self.badExtensionsButton.setBounds(355, 175, 70, 30)

        self.badExtensionsDefaultButton = JButton("Load Defaults")
        self.badExtensionsDefaultButton.addActionListener(
            self.handleBadExtensionsDefaultButton)
        self.badExtensionsDefaultButton.setBounds(430, 175, 120, 30)

        self.badMimesLabel = JLabel("Ignore mime types:")
        self.badMimesLabel.setBounds(X_BASE, 220, 200, 30)

        self.badMimesText = JTextArea("")
        self.loadBadMimes()
        self.badMimesText.setBounds(X_BASE, 245, 310, 30)

        self.badMimesButton = JButton("Save")
        self.badMimesButton.addActionListener(self.handleBadMimesButton)
        self.badMimesButton.setBounds(355, 245, 70, 30)

        self.badMimesDefaultButton = JButton("Load Defaults")
        self.badMimesDefaultButton.addActionListener(
            self.handleBadMimesDefaultButton)
        self.badMimesDefaultButton.setBounds(430, 245, 120, 30)

        self.otherLabel = JLabel("Other:")
        self.otherLabel.setBounds(40, 300, 120, 30)

        self.otherLabel2 = JLabel("Other:")
        self.otherLabel2.setBounds(X_BASE, Y_OPTION, 120, 30)

        self.autoSaveOption = JCheckBox("Auto save periodically")
        self.autoSaveOption.setSelected(True)
        self.autoSaveOption.addActionListener(self.handleAutoSaveOption)
        self.autoSaveOption.setBounds(X_BASE, Y_OPTION + Y_CHECKMARK_SPACING,
                                      420, 30)

        self.repeaterOptionButton = JCheckBox(
            "Repeater request automatically marks as analyzed")
        self.repeaterOptionButton.setSelected(True)
        self.repeaterOptionButton.addActionListener(
            self.handleRepeaterOptionButton)
        self.repeaterOptionButton.setBounds(50, 330, 420, 30)

        self.scopeOptionButton = JCheckBox("Follow Burp Target In Scope rules")
        self.scopeOptionButton.setSelected(True)
        self.scopeOptionButton.addActionListener(self.handleScopeOptionButton)
        self.scopeOptionButton.setBounds(50, 350, 420, 30)

        self.startOptionButton = JCheckBox("Autostart Scope Monitor")
        self.startOptionButton.setSelected(True)
        self.startOptionButton.addActionListener(self.handleStartOption)
        self.startOptionButton.setBounds(50, 350 + Y_OPTION_SPACING, 420, 30)

        self.markTestedRequestsProxy = JCheckBox(
            "Color request in Proxy tab if analyzed")
        self.markTestedRequestsProxy.setSelected(True)
        self.markTestedRequestsProxy.addActionListener(
            self.handleTestedRequestsProxy)
        self.markTestedRequestsProxy.setBounds(50, 350 + Y_OPTION_SPACING * 2,
                                               420, 30)

        self.markNotTestedRequestsProxy = JCheckBox(
            "Color request in Proxy tab if NOT analyzed")
        self.markNotTestedRequestsProxy.setSelected(True)
        self.markNotTestedRequestsProxy.addActionListener(
            self.handleNotTestedRequestsProxy)
        self.markNotTestedRequestsProxy.setBounds(50,
                                                  350 + Y_OPTION_SPACING * 3,
                                                  420, 30)

        self.saveButton = JButton("Save now")
        self.saveButton.addActionListener(self.handleSaveButton)
        self.saveButton.setBounds(X_BASE + 320, 95, 90, 30)

        self.loadButton = JButton("Load now")
        self.loadButton.addActionListener(self.handleLoadButton)
        self.loadButton.setBounds(X_BASE + 420, 95, 90, 30)

        self.selectPath = JButton("Select path")
        self.selectPath.addActionListener(self.selectExportFile)
        self.selectPath.setBounds(X_BASE + 530, 60, 120, 30)

        self.selectPathText = JTextArea("")
        self.selectPathText.setBounds(X_BASE, 60, 510, 30)

        self.selectPathLabel = JLabel("State file:")
        self.selectPathLabel.setBounds(X_BASE, 30, 200, 30)

        bGroup = ButtonGroup()

        bGroup.add(self.showAllButton)
        bGroup.add(self.showNewButton)
        bGroup.add(self.showTestedButton)

        config.add(self.clearButton)
        config.add(self.startButton)
        config.add(self.startOptionButton)
        config.add(self.showAllButton)
        config.add(self.showNewButton)
        config.add(self.showTestedButton)

        config.add(self.badExtensionsButton)
        config.add(self.badExtensionsText)
        config.add(self.badExtensionsLabel)

        config.add(self.badMimesButton)
        config.add(self.badMimesText)
        config.add(self.badMimesLabel)

        config.add(self.badExtensionsDefaultButton)
        config.add(self.badMimesDefaultButton)

        config.add(self.otherLabel)
        config.add(self.repeaterOptionButton)
        config.add(self.scopeOptionButton)
        config.add(self.markTestedRequestsProxy)
        config.add(self.markNotTestedRequestsProxy)

        iexport.add(self.saveButton)
        iexport.add(self.loadButton)
        iexport.add(self.selectPath)
        iexport.add(self.selectPathText)
        iexport.add(self.selectPathLabel)
        iexport.add(self.otherLabel2)
        iexport.add(self.autoSaveOption)

        self._config.addTab("General", config)
        self._config.addTab("Import/Export", iexport)

        ##### end config pane

        self._parentPane.addTab("Monitor", self._splitpane)
        self._parentPane.addTab("Config", self._config)

        # table of log entries
        self.logTable = Table(self)

        #self.logTable.setDefaultRenderer(self.logTable.getColumnClass(0), ColoredTableCellRenderer(self))

        self.logTable.setAutoCreateRowSorter(True)
        self.logTable.setRowSelectionAllowed(True)

        renderer = ColoredTableCellRenderer(self)
        #column = TableColumn(0, 190, renderer, None)

        print 'Initiating... '

        # this could be improved by fetching initial dimensions
        self.logTable.getColumn("URL").setPreferredWidth(720)  # noscope
        self.logTable.getColumn("URL").setResizable(True)

        self.logTable.getColumn("Checked").setCellRenderer(renderer)
        self.logTable.getColumn("Checked").setPreferredWidth(80)
        self.logTable.getColumn("Checked").setMaxWidth(80)

        self.logTable.getColumn("Method").setPreferredWidth(120)
        #self.logTable.getColumn("Method").setMaxWidth(120)
        self.logTable.getColumn("Method").setResizable(True)

        self.logTable.getColumn("Time").setPreferredWidth(120)  # noscope
        self.logTable.getColumn("Time").setResizable(True)

        scrollPane = JScrollPane(self.logTable)
        self._splitpane.setLeftComponent(scrollPane)

        # tabs with request/response viewers
        tabs = JTabbedPane()
        self._requestViewer = callbacks.createMessageEditor(self, False)
        self._responseViewer = callbacks.createMessageEditor(self, False)
        tabs.addTab("Request", self._requestViewer.getComponent())
        tabs.addTab("Response", self._responseViewer.getComponent())
        self._splitpane.setRightComponent(tabs)

        ## Row sorter shit

        #self._tableRowSorterAutoProxyAutoAction = CustomTableRowSorter(self.logTable.getModel())
        #self.logTable.setRowSorter(self._tableRowSorterAutoProxyAutoAction)

        markAnalyzedButton = JMenuItem("Mark Requests as Analyzed")
        markAnalyzedButton.addActionListener(markRequestsHandler(self, True))

        markNotAnalyzedButton = JMenuItem("Mark Requests as NOT Analyzed")
        markNotAnalyzedButton.addActionListener(
            markRequestsHandler(self, False))

        sendRequestMenu = JMenuItem("Send Request to Repeater")
        sendRequestMenu.addActionListener(sendRequestRepeater(self))

        deleteRequestMenu = JMenuItem("Delete request")
        deleteRequestMenu.addActionListener(deleteRequestHandler(self))

        self.menu = JPopupMenu("Popup")
        self.menu.add(markAnalyzedButton)
        self.menu.add(markNotAnalyzedButton)
        self.menu.add(sendRequestMenu)
        self.menu.add(deleteRequestMenu)

        # customize our UI components
        callbacks.customizeUiComponent(self._parentPane)
        callbacks.customizeUiComponent(self._splitpane)
        callbacks.customizeUiComponent(self._config)
        callbacks.customizeUiComponent(config)
        callbacks.customizeUiComponent(self.logTable)
        callbacks.customizeUiComponent(scrollPane)
        callbacks.customizeUiComponent(tabs)

        callbacks.registerContextMenuFactory(self)
        callbacks.registerExtensionStateListener(self)
        callbacks.registerScannerCheck(passiveScanner(self))

        # add the custom tab to Burp's UI
        callbacks.addSuiteTab(self)

        # register ourselves as an HTTP listener
        callbacks.registerHttpListener(self)

        self.loadConfigs()

        print "Loaded!"

        print "Experimental import state.. "
        self.importState("")

        self.SC = sched.scheduler(time.time, time.sleep)
        self.SCC = self.SC.enter(10, 1, self.autoSave, (self.SC, ))
        self.SC.run()

        return

    ##### CUSTOM CODE #####
    def loadConfigs(self):

        if self._callbacks.loadExtensionSetting("CONFIG_AUTOSTART") == "False":
            self.startOptionButton.setSelected(False)
            self.startOrStop(None, False)
        else:
            self.startOptionButton.setSelected(True)
            self.startOrStop(None, True)

        if self._callbacks.loadExtensionSetting("exportFile") != "":
            self.selectPathText.setText(
                self._callbacks.loadExtensionSetting("exportFile"))

        if self._callbacks.loadExtensionSetting("CONFIG_REPEATER") == "True":
            self.repeaterOptionButton.setSelected(True)
        else:
            self.repeaterOptionButton.setSelected(False)

        if self._callbacks.loadExtensionSetting("CONFIG_INSCOPE") == "True":
            self.scopeOptionButton.setSelected(True)
        else:
            self.scopeOptionButton.setSelected(False)

        if self._callbacks.loadExtensionSetting("CONFIG_AUTOSAVE") == "True":
            self.autoSaveOption.setSelected(True)
        else:
            self.autoSaveOption.setSelected(False)

        if self._callbacks.loadExtensionSetting(
                "CONFIG_HIGHLIGHT_TESTED") == "True":
            self.markTestedRequestsProxy.setSelected(True)
        else:
            self.markTestedRequestsProxy.setSelected(False)

        if self._callbacks.loadExtensionSetting(
                "CONFIG_HIGHLIGHT_NOT_TESTED") == "True":
            self.markNotTestedRequestsProxy.setSelected(True)
        else:
            self.markNotTestedRequestsProxy.setSelected(False)

        return

    def selectExportFile(self, event):
        parentFrame = JFrame()
        fileChooser = JFileChooser()
        fileChooser.setDialogTitle("Specify file to save state")
        fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY)

        userSelection = fileChooser.showOpenDialog(parentFrame)

        if (userSelection == JFileChooser.APPROVE_OPTION):
            fileLoad = fileChooser.getSelectedFile()
            filename = fileLoad.getAbsolutePath()

            self.selectPathText.setText(filename)
            print 'Filename selected:' + filename
            self._callbacks.saveExtensionSetting("exportFile", filename)

        return

    def extensionUnloaded(self):
        print 'extension unloading.. '

        print 'canceling scheduler.. '
        map(self.SC.cancel, self.SC.queue)
        return

    def loadBadExtensions(self):
        bad = self._callbacks.loadExtensionSetting("badExtensions")
        if bad:
            self.badExtensionsText.setText(bad)
            # transform text to array
            bad = bad.replace(" ", "")
            self.BAD_EXTENSIONS = bad.split(",")
        else:
            print 'no bad extension saved, reverting'
            self.badExtensionsText.setText(", ".join(self.BAD_EXTENSIONS))

    def loadBadMimes(self):
        bad = self._callbacks.loadExtensionSetting("badMimes")
        if bad:
            self.badMimesText.setText(bad)

            bad = bad.replace(" ", "")
            self.BAD_MIMES = bad.split(",")
        else:
            print 'no bad mimes saved, reverting'
            self.badMimesText.setText(", ".join(self.BAD_MIMES))

    ## GLOBAL CONTEXT CODE ##

    def createMenuItems(self, invocation):
        responses = invocation.getSelectedMessages()
        if responses > 0:
            ret = LinkedList()
            analyzedMenuItem = JMenuItem("Mark as analyzed")
            notAnalyzedMenuItem = JMenuItem("Mark as NOT analyzed")

            for response in responses:
                analyzedMenuItem.addActionListener(
                    handleMenuItems(self, response, "analyzed"))
                notAnalyzedMenuItem.addActionListener(
                    handleMenuItems(self, response, "not"))
            ret.add(analyzedMenuItem)
            ret.add(notAnalyzedMenuItem)
            return ret

    def getEndpoint(self, requestResponse):
        url_ = str(self._helpers.analyzeRequest(requestResponse).getUrl())
        o = urlparse(url_)

        url = o.scheme + "://" + o.netloc + o.path
        #print "Url3: " + url
        return url

    def getMethod(self, requestResponse):
        return self._helpers.analyzeRequest(requestResponse).getMethod()

    ##### CUSTOM CODE #####
    def handleTestedRequestsProxy(self, event):
        self._callbacks.saveExtensionSetting(
            "CONFIG_HIGHLIGHT_TESTED",
            str(self.markTestedRequestsProxy.isSelected()))
        return

    def handleNotTestedRequestsProxy(self, event):
        self._callbacks.saveExtensionSetting(
            "CONFIG_HIGHLIGHT_NOT_TESTED",
            str(self.markNotTestedRequestsProxy.isSelected()))
        return

    def handleStartOption(self, event):
        self._callbacks.saveExtensionSetting(
            "CONFIG_AUTOSTART", str(self.startOptionButton.isSelected()))
        #print 'saving autostart: ' + str(self.startOptionButton.isSelected())
        return

    def startOrStop(self, event, autoStart):
        if (self.startButton.getText() == MONITOR_OFF_LABEL) or autoStart:
            self.startButton.setText(MONITOR_ON_LABEL)
            self.startButton.setBackground(GREEN_COLOR)
            self.STATUS = True
        else:
            self.startButton.setText(MONITOR_OFF_LABEL)
            self.startButton.setBackground(RED_COLOR)
            self.STATUS = False

    def handleStartButton(self, event):
        self.startOrStop(event, False)

    def handleAutoSaveOption(self, event):
        self._callbacks.saveExtensionSetting(
            "CONFIG_AUTOSAVE", str(self.autoSaveOption.isSelected()))
        return

    def handleSaveButton(self, event):
        self.exportState("")

    def handleLoadButton(self, event):
        self.importState("")

    def handleRepeaterOptionButton(self, event):
        self._callbacks.saveExtensionSetting(
            "CONFIG_REPEATER", str(self.repeaterOptionButton.isSelected()))
        return

    def handleScopeOptionButton(self, event):
        self.CONFIG_INSCOPE = self.scopeOptionButton.isSelected()
        self._callbacks.saveExtensionSetting("CONFIG_INSCOPE",
                                             str(self.CONFIG_INSCOPE))
        return

    def handleBadExtensionsButton(self, event):
        #print "before BAD array: "
        print self.BAD_EXTENSIONS

        extensions = self.badExtensionsText.getText()
        self._callbacks.saveExtensionSetting("badExtensions", extensions)
        print 'New extensions blocked: ' + extensions
        bad = extensions.replace(" ", "")
        self.BAD_EXTENSIONS = bad.split(",")
        #print "BAD array: "
        #print self.BAD_EXTENSIONS

    def handleBadExtensionsDefaultButton(self, event):
        self.BAD_EXTENSIONS = self.BAD_EXTENSIONS_DEFAULT
        self.badExtensionsText.setText(", ".join(self.BAD_EXTENSIONS))
        self._callbacks.saveExtensionSetting("badExtensions",
                                             ", ".join(self.BAD_EXTENSIONS))
        return

    def handleBadMimesDefaultButton(self, event):
        self.BAD_MIMES = self.BAD_MIMES_DEFAULT
        self.badMimesText.setText(", ".join(self.BAD_MIMES))
        self._callbacks.saveExtensionSetting("badExtensions",
                                             ", ".join(self.BAD_MIMES))
        return

    def handleBadMimesButton(self, event):
        mimes = self.badMimesText.getText()
        self._callbacks.saveExtensionSetting("badMimes", mimes)
        print 'New mimes blocked: ' + mimes
        bad = mimes.replace(" ", "")
        self.BAD_MIMES = bad.split(",")

    def handleClearButton(self, event):
        print 'Clearing table'
        self._lock.acquire()
        self._log = ArrayList()
        self._fullLog = ArrayList()
        self._lock.release()
        return

    def handleRadioConfig(self, event):
        #print ' radio button clicked '
        #print event.getActionCommand()
        self._lock.acquire()

        if event.getActionCommand() == SHOW_ALL_BUTTON_LABEL:
            print "Showing all"
            self._log = self._fullLog
        elif event.getActionCommand() == SHOW_NEW_BUTTON_LABEL:
            print "Showing new scope only"
            tmpLog = ArrayList()
            for item in self._fullLog:
                if not (item._analyzed):
                    tmpLog.add(item)
            self._log = tmpLog
        elif event.getActionCommand() == SHOW_TEST_BUTTON_LABEL:
            print "Showing tested scope only"
            tmpLog = ArrayList()
            for item in self._fullLog:
                if item._analyzed:
                    tmpLog.add(item)
            self._log = tmpLog
        else:
            print "unrecognized radio label"

        self.fireTableDataChanged()
        #self._tableRowSorterAutoProxyAutoAction.toggleSortOrder(1)
        #self.toggleSortOrder(2)

        #self.logTable.toggleSortOrder(2)

        # refresh table?

        self._lock.release()

    #
    # implement ITab
    #

    def getTabCaption(self):
        return "Scope Monitor"

    def getUiComponent(self):
        return self._parentPane

    #
    # implement IHttpListener
    #

    def markAnalyzed(self, messageIsRequest, state):
        #print "markAnalyzed..."
        self._lock.acquire()

        url = self.getEndpoint(messageIsRequest)
        for item in self._log:
            if url == item._url:
                item._analyzed = state
                self._lock.release()
                return
        self._lock.release()
        return

    def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
        # only process requests

        #print "processing httpMessage.."
        #print messageIsRequest

        print "processHttpMessage toolFlag: " + str(toolFlag)
        #print " -- " + str(self._callbacks.getToolName(toolFlag)) + " -- "

        if not (self.STATUS):
            return

        #print "global handler status: (true): " + str(self.GLOBAL_HANDLER)
        #print "(processHTTP) messageIsRequest"
        #print messageIsRequest

        isFromPassiveScan = False
        if toolFlag == 1234:
            print "1 processHttpMessage: processing passiveScan item"
            isFromPassiveScan = True

        if toolFlag != 1234:
            if messageIsRequest and not (self.GLOBAL_HANDLER):
                print "1.5 processHttpMessage droping message"
                return

        if self.scopeOptionButton.isSelected():
            url = self._helpers.analyzeRequest(messageInfo).getUrl()
            if not self._callbacks.isInScope(url):
                #print 'Url not in scope, skipping.. '
                return

        #print "still processing httpMessage.., request came from: " + self._callbacks.getToolName(toolFlag)
        if toolFlag == 1234:
            print "2 processHttpMessage: processing passiveScan item; setting toolFlag to proxy (4)"
            toolFlag = 4

        #toolFlag = 4
        if ((self._callbacks.getToolName(toolFlag) != "Repeater")
                and (self._callbacks.getToolName(toolFlag) != "Proxy")
                and (self._callbacks.getToolName(toolFlag) != "Target")):
            #print 'Aborting processHTTP, request came from: ' + str(self._callbacks.getToolName(toolFlag))
            print "Droping request from " + str(
                self._callbacks.getToolName(toolFlag))
            return

        #print "---> still processing from tool: " + str(self._callbacks.getToolName(toolFlag))

        url = self.getEndpoint(messageInfo)
        method = self.getMethod(messageInfo)

        #print "(processHTTP) before extensions check: " + url

        for extension in self.BAD_EXTENSIONS:
            if url.endswith(extension):
                return

        if messageInfo.getResponse():
            mime = self._helpers.analyzeResponse(
                messageInfo.getResponse()).getStatedMimeType()
            #print 'Declared mime:' + mime
            mime = mime.lower()
            if mime in self.BAD_MIMES:
                #print 'Bad mime:' + mime
                return

        #print "[httpMessage] before lock"
        # create a new log entry with the message details
        self._lock.acquire()
        row = self._log.size()

        for item in self._log:
            if url == item._url:
                if method == self._helpers.analyzeRequest(
                        item._requestResponse).getMethod():
                    #print 'duplicate URL+method, skipping.. '
                    self._lock.release()

                    # has it been analyzed?
                    analyzed = False
                    if self._callbacks.getToolName(toolFlag) == "Repeater":
                        if self.repeaterOptionButton.isSelected():
                            analyzed = True
                            #print "[httpMessage] setting analyzed as true"
                    if self.GLOBAL_HANDLER_ANALYZED:
                        analyzed = True

                    item._analyzed = analyzed
                    self.paintItems(messageInfo, item)

                    return

        #print "[httpMessage] before setComment"
        if not (isFromPassiveScan):
            messageInfo.setComment(SCOPE_MONITOR_COMMENT)
        # reached here, must be new entry
        analyzed = False
        if self._callbacks.getToolName(toolFlag) == "Repeater":
            if self.repeaterOptionButton.isSelected():
                analyzed = True
                #print "[httpMessage] setting analyzed as true"
        if self.GLOBAL_HANDLER_ANALYZED:
            analyzed = True

        #print "[httpMessage] after comment"
        #print 'in httpmessage, response:'
        #print self._helpers.analyzeResponse(messageInfo.getResponse())

        date = datetime.datetime.fromtimestamp(
            time.time()).strftime('%H:%M:%S %d %b %Y')
        entry = LogEntry(toolFlag,
                         self._callbacks.saveBuffersToTempFiles(messageInfo),
                         url, analyzed, date, method)
        #print "toolFlag: " + str(toolFlag)

        #print "(processHTTP) Adding URL: " + url
        self._log.add(entry)
        self._fullLog.add(entry)
        self.fireTableRowsInserted(row, row)

        self.paintItems(messageInfo, entry)

        self._lock.release()

        #print "columnCoun:" + str(self.logTable.getColumnCount())

    #
    # extend AbstractTableModel
    #

    def paintItems(self, messageInfo, item):
        '''
        print "in paint Items"
        print "mark color is: (true)" + str(self.markTestedRequestsProxy.isSelected())
        print "global handler analyzed:           :" + str(self.GLOBAL_HANDLER_ANALYZED)
        print "item analyzed should be the same ^^:" + str(item._analyzed)
        '''
        if (self.markTestedRequestsProxy.isSelected()) and (
                item._analyzed and self.GLOBAL_HANDLER_ANALYZED):
            messageInfo.setHighlight("green")
            return

        if self.markNotTestedRequestsProxy.isSelected() and not (
                item._analyzed):
            messageInfo.setHighlight("red")

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

    def getColumnCount(self):
        return 4

    def getColumnName(self, columnIndex):
        if columnIndex == 0:
            return "Checked"
        if columnIndex == 1:
            return "URL"
        if columnIndex == 2:
            return "Method"
        if columnIndex == 3:
            return "Time"

    def getValueAt(self, rowIndex, columnIndex):
        logEntry = self._log.get(rowIndex)

        #self.setBackground(Color.GREEN)
        return self.returnEntry(rowIndex, columnIndex, logEntry)

        if self.showNewButton.isSelected() and not (logEntry._analyzed):
            return self.returnEntry(rowIndex, columnIndex, logEntry)
        elif self.showTestedButton.isSelected() and logEntry._analyzed:
            return self.returnEntry(rowIndex, columnIndex, logEntry)
        elif self.showAllButton.isSelected():
            return self.returnEntry(rowIndex, columnIndex, logEntry)

    def returnEntry(self, rowIndex, columnIndex, entry):
        logEntry = self._log.get(rowIndex)
        if columnIndex == 0:
            if logEntry._analyzed:
                return "True"
            else:
                return "False"
        if columnIndex == 1:
            return self._helpers.urlDecode(logEntry._url)
        if columnIndex == 2:
            return logEntry._method
        if columnIndex == 3:
            return logEntry._date
            # return date
        return ""

    #
    # implement IMessageEditorController
    # this allows our request/response viewers to obtain details about the messages being displayed
    #

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

    def getRequest(self):
        #print 'getRequest called'
        return self._currentlyDisplayedItem.getRequest()

    def getResponse(self):
        #print 'getResponse called: '
        print self._currentlyDisplayedItem.getResponse()
        return self._currentlyDisplayedItem.getResponse()

    def exportRequest(self, entity, filename):

        line = str(entity._analyzed) + ","
        line = line + self._helpers.urlEncode(entity._url).replace(
            ",", "%2c") + ","  # URL is encoded so we should be good
        line = line + entity._method + ","
        line = line + entity._date
        line = line + '\n'

        #print 'Exporting: "' + line + '"'
        return line

    def exportUrlEncode(self, url):
        return self._helpers.urlEncode(url).replace(",", "%2c")

    def exportState(self, filename):
        filename = self.selectPathText.getText()

        if filename == "":
            filename = self._callbacks.loadExtensionSetting("exportFile")
            print 'Empty filename, skipping export'
            return
        else:
            self._callbacks.saveExtensionSetting("exportFile", filename)

        print 'saving state to: ' + filename

        savedUrls = []

        self._lockFile.acquire()
        try:
            with open(filename, 'r') as fr:
                savedEntries = fr.read().splitlines()
                savedUrls = []
                for savedEntry in savedEntries:
                    savedUrls.append(savedEntry.split(",")[1])
                #print "savedUrls len: " + str(len(savedUrls))
                #print "savedUrls:"
                #print savedUrls
                fr.close()
        except IOError:
            print "Autosaving skipped as file doesn't exist yet"

        with open(filename, 'a+') as f:

            for item in self._log:
                if self.exportUrlEncode(item._url) not in savedUrls:
                    line = self.exportRequest(item, "xx")
                    f.write(line)
            f.close()
        self._lockFile.release()

        return

    def importState(self, filename):
        filename = self.selectPathText.getText()

        if filename == "":
            filename = self._callbacks.loadExtensionSetting("exportFile")
            print 'Empty filename, skipping import'
            return
        else:
            self._callbacks.saveExtensionSetting("exportFile", filename)

        print 'loading state from: ' + filename

        self.STATUS = False

        self._lockFile.acquire()
        with open(filename, 'r') as f:

            proxy = self._callbacks.getProxyHistory()

            proxyItems = []
            for item in proxy:
                if item.getComment():
                    if SCOPE_MONITOR_COMMENT in item.getComment():
                        proxyItems.append(item)

            print 'proxyItems has: ' + str(len(proxyItems))
            # TODO - if no proxy items, sraight to import

            lines = f.read().splitlines()
            for line in lines:
                data = line.split(",")
                url = data[1]
                url = self._helpers.urlDecode(url)

                #print 'Saving: ' + url
                if not self._callbacks.isInScope(URL(url)):
                    print '-- imported url not in scope, skipping.. '
                    continue

                analyzed = False
                if data[0] == "True":
                    analyzed = True

                #print '.. simulating url search.. '
                requestResponse = None
                for request in proxyItems:
                    if url == self.getEndpoint(request):
                        #print 'Match found when importing for url: ' + url
                        requestResponse = request
                        break

                self._log.add(
                    LogEntry("", requestResponse, url, analyzed, data[3],
                             data[2]))

            self._lockFile.release()
        print 'finished loading.. '
        #print 'size: ' + str(self._log.size())
        self.fireTableDataChanged()

        if self.startButton.getText() == MONITOR_ON_LABEL:
            self.STATUS = True

        return

    def autoSave(self, sc):
        #print 'autosaving.. lol what'
        if self.autoSaveOption.isSelected():
            print "[" + self.getTime(
            ) + "] autosaving to " + self._callbacks.loadExtensionSetting(
                "exportFile")
            self.exportState("")

        self.SC.enter(self.AUTOSAVE_TIMEOUT, 1, self.autoSave, (self.SC, ))
        return

    def getTime(self):
        date = datetime.datetime.fromtimestamp(
            time.time()).strftime('%H:%M:%S')
        return date
Esempio n. 24
0
class BurpExtender(IBurpExtender, ITab):
    socket_time_out = 3

    def registerExtenderCallbacks(self, callbacks):
        self.out = callbacks.getStdout()

        self.callbacks = callbacks
        self.helpers = callbacks.getHelpers()
        callbacks.setExtensionName("WhatsApp Decoder")

        self.banner = JLabel("WHATSAPP DECRYPTION AND ENCRYPTION EXTENSION BY DIKLA BARDA, ROMAN ZAIKIN", SwingConstants.CENTER)
        self.banner.setFont(Font("Serif", Font.PLAIN, 17))
        self.banner.setBorder(BorderFactory.createLineBorder(Color.BLACK))

        self.statusConn = JLabel("CONNECTION STATUS:  ")
        self.statusConnField = JLabel("NOT CONNECTED")
        self.statusAct = JLabel("ACTION STATUS:      ")
        self.statusActField = JLabel("OK")

        self.ref = JLabel("Ref object:  ")
        self.refField = JTextField("123", 80)
        self.refField.setToolTipText("Copy the Ref from burpsuit WebSocket, make sure that the parameter 'secret' is there and you copy only the 'ref' without the connection and other data, if not logout from your whatsapp web and login again.")

        self.privateKey = JLabel("Private Key:")
        self.privateKeyField = JTextField("123", 80)
        self.privateKeyField.setToolTipText("Copy the private key list from your whatsapp web according to our blog post ")

        self.publicKey = JLabel("Public Key: ")
        self.publicKeyField = JTextField("123", 80)
        self.publicKeyField.setToolTipText("Copy the public key list from your whatsapp web according to our blog post")

        self.statusPanel1 = JPanel()
        self.statusPanel1.add(self.statusConn)
        self.statusPanel1.add(self.statusConnField)

        self.statusPanel2 = JPanel()
        self.statusPanel2.add(self.statusAct)
        self.statusPanel2.add(self.statusActField)

        self.privateKeyPanel = JPanel()
        self.privateKeyPanel.add(self.privateKey)
        self.privateKeyPanel.add(self.privateKeyField)

        self.publicKeyPanel = JPanel()
        self.publicKeyPanel.add(self.publicKey)
        self.publicKeyPanel.add(self.publicKeyField)

        self.refPanel = JPanel()
        self.refPanel.add(self.ref)
        self.refPanel.add(self.refField)

        self.messageField = JTextArea("", 5, 90)
        self.messageField.setLineWrap(True)
        self.messageField.setToolTipText("If you putting in the incoming traffic you can copy it from burp suit, the outgoing is the list from aesCbcEncrypt")

        self.whatsAppMessagesPanel = JPanel()
        self.whatsAppMessagesPanel.add(self.messageField)

        self.btnSave = JButton("Connect", actionPerformed=self.saveConfig)
        self.btnRestore = JButton("Clear", actionPerformed=self.clearConfig)

        self.grpConfig = JPanel()
        self.grpConfig.add(self.btnSave)
        self.grpConfig.add(self.btnRestore)

        self.btnIncoming = JButton("Incoming", actionPerformed=self.performAction)
        self.btnOutgoing = JButton("Outgoing", actionPerformed=self.performAction)

        self.btnEncrypt = JButton("Encrypt", actionPerformed=self.performAction)
        self.btnEncrypt.setEnabled(False)  # Can't send data without a direction

        self.btnDecrypt = JButton("Decrypt", actionPerformed=self.performAction)
        self.btnDecrypt.setEnabled(False)  # Can't send data without a direction

        self.btnCrypt = JPanel()
        self.btnCrypt.add(self.btnIncoming)
        self.btnCrypt.add(self.btnEncrypt)
        self.btnCrypt.add(self.btnDecrypt)
        self.btnCrypt.add(self.btnOutgoing)

        self.tab = JPanel()
        layout = GridBagLayout()
        self.tab.setLayout(layout)

        c = GridBagConstraints()

        c.ipadx = 0
        c.ipady = 0

        c.fill = GridBagConstraints.BOTH
        #c.weightx = 0 # gap between the x items
        #c.weighty = 0 # gap between the y items

        c.anchor = GridBagConstraints.NORTHWEST

        c.gridx = 0
        c.gridy = 0
        self.tab.add(self.banner, c)

        c.gridx = 0
        c.gridy = 1
        self.tab.add(self.refPanel, c)

        c.gridx = 0
        c.gridy = 2
        self.tab.add(self.privateKeyPanel, c)

        c.gridx = 0
        c.gridy = 3
        self.tab.add(self.publicKeyPanel, c)

        c.gridx = 0
        c.gridy = 4
        c.anchor = GridBagConstraints.CENTER
        self.tab.add(self.grpConfig, c)

        c.gridx = 0
        c.gridy = 5
        self.tab.add(self.whatsAppMessagesPanel, c)

        c.gridx = 0
        c.gridy = 6
        self.tab.add(self.btnCrypt, c)

        c.gridx = 0
        c.gridy = 7
        self.tab.add(self.statusPanel1, c)

        c.gridx = 0
        c.gridy = 8
        self.tab.add(self.statusPanel2, c)

        # restore config
        self.restoreConfig()
        callbacks.addSuiteTab(self)

    def performAction(self, e=None):

        self.client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.client.settimeout(self.socket_time_out)

        self.data = self.messageField.getText()

        eventSource = e.getSource()
        eventSource.setEnabled(False)

        # Incoming data
        if eventSource == self.btnIncoming:
            self.direction = "in"
            self.btnOutgoing.setEnabled(True)
            self.btnEncrypt.setEnabled(True)
            self.btnDecrypt.setEnabled(True)

        # Outgoing data
        elif eventSource == self.btnOutgoing:
            self.direction = "out"
            self.btnIncoming.setEnabled(True)
            self.btnEncrypt.setEnabled(True)
            self.btnDecrypt.setEnabled(True)

        # Send
        elif eventSource == self.btnDecrypt:
            self.btnDecrypt.setEnabled(True)
            clientData = json.dumps({"action": "decrypt",
                                     "data": {
                                            "direction": self.direction,
                                            "msg": self.messageField.getText()
                                        }
                                     })

            self.client.sendto(clientData, ("127.0.0.1",2912))
            try:
                serverData, addr = self.client.recvfrom(2048)
                serverData = json.loads(serverData)

                if serverData["status"] == 0:
                    print serverData
                    self.messageField.setText(json.dumps(serverData["data"]))
                    self.statusActField.setForeground(Color.GREEN)
                    self.statusActField.setText("OK")
                else:
                    self.statusActField.setForeground(Color.RED)
                    self.statusActField.setText("Error: {}".format(json.dumps(serverData["data"])))

            except socket.timeout:
                pass

        elif eventSource == self.btnEncrypt:
            self.btnEncrypt.setEnabled(True)
            clientData = json.dumps({"action": "encrypt",
                                     "data": {
                                         "direction": self.direction,
                                         "msg": self.messageField.getText()
                                     }
                                     })

            self.client.sendto(clientData, ("127.0.0.1", 2912))
            try:
                serverData, addr = self.client.recvfrom(2048)
                serverData = json.loads(serverData)
                if serverData["status"] == 0:
                    if isinstance(serverData["data"], list):
                        self.messageField.setText(json.dumps(serverData["data"]))
                    else:
                        self.messageField.setText(serverData["data"])

                    self.statusActField.setForeground(Color.GREEN)
                    self.statusActField.setText("OK")
                else:
                    self.statusActField.setForeground(Color.RED)
                    self.statusActField.setText("Error: {}".format(json.dumps(serverData["data"])))

            except socket.timeout:
                pass

        self.client.close()


    def saveConfig(self, e=None):
        self.client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.client.settimeout(self.socket_time_out)

        config = {
            'ref': self.refField.getText(),
            'private': self.privateKeyField.getText(),
            'public': self.publicKeyField.getText(),
        }

        self.callbacks.saveExtensionSetting("config", pickle.dumps(config))

        try:
            clientData = json.dumps({"action":"init",
                                     "data":{
                                         "ref":json.loads(self.refField.getText()),
                                         "private":self.privateKeyField.getText(),
                                         "public":self.publicKeyField.getText()
                                     }
                                    })

            self.client.sendto(clientData, ("127.0.0.1", 2912))

            serverData, addr = self.client.recvfrom(2048)
            print (serverData)

            self.statusConnField.setText("CONNECTED")
            self.statusActField.setForeground(Color.GREEN)
            self.statusActField.setText("OK")

        except socket.timeout:
            self.statusActField.setForeground(Color.RED)
            self.statusActField.setText("Error: Can't connect to the local server make sure parser.py is running!")
            pass

        except Exception as e:
            self.statusActField.setForeground(Color.RED)
            self.statusActField.setText("Error: make Sure the ref is a correct json!")

        self.client.close()

    def clearConfig(self, e=None):
        self.refField.setText("")
        self.privateKeyField.setText("")
        self.publicKeyField.setText("")
        self.statusConnField.setText("NOT CONNECTED")
        self.statusActField.setText("OK")
        self.messageField.setText("")

    def restoreConfig(self, e=None):
        storedConfig = self.callbacks.loadExtensionSetting("config")
        if storedConfig != None:
            config = pickle.loads(storedConfig)
            self.refField.setText(config["ref"])
            self.privateKeyField.setText(config["private"])
            self.publicKeyField.setText(config["public"])

    def getTabCaption(self):
        return ("WhatsApp Decoder")

    def getUiComponent(self):
        return self.tab
Esempio n. 25
0
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, IContextMenuFactory):

    def registerExtenderCallbacks(self, callbacks):
        # keep a reference to our callbacks object
        self._callbacks = callbacks
        # obtain an extension helpers object
        self._helpers = callbacks.getHelpers()
        
        # set our extension name
        callbacks.setExtensionName("Autorize")
        
        # create the log and a lock on which to synchronize when adding log entries
        self._log = ArrayList()
        self._lock = Lock()
        self._enfocementStatuses = ["Authorization bypass!","Authorization enforced??? (please configure enforcement detector)","Authorization enforced!"]
        self.intercept = 0

        self.initInterceptionFilters()

        self.initEnforcementDetector()

        self.initEnforcementDetectorUnauthorized()

        self.initExport()

        self.initConfigurationTab()

        self.initTabs()
        
        self.initCallbacks()

        self.currentRequestNumber = 1
        
        print "Thank you for installing Autorize v0.12 extension"
        print "Created by Barak Tawily" 
        print "Contributors: Barak Tawily, Federico Dotta"
        print "\nGithub:\nhttps://github.com/Quitten/Autorize"
        return
        

    def initExport(self):
        #
        ## init enforcement detector tab
        #

        exportLType = JLabel("File Type:")
        exportLType.setBounds(10, 10, 100, 30)
       
        exportLES = JLabel("Enforcement Statuses:")
        exportLES.setBounds(10, 50, 160, 30)

        exportFileTypes = ["HTML","CSV"]
        self.exportType = JComboBox(exportFileTypes)
        self.exportType.setBounds(100, 10, 200, 30)

        exportES = ["All Statuses", self._enfocementStatuses[0], self._enfocementStatuses[1], self._enfocementStatuses[2]]
        self.exportES = JComboBox(exportES)
        self.exportES.setBounds(100, 50, 200, 30)

        exportLES = JLabel("Statuses:")
        exportLES.setBounds(10, 50, 100, 30)

        self.exportButton = JButton("Export",actionPerformed=self.export)
        self.exportButton.setBounds(390, 25, 100, 30)

        self.exportPnl = JPanel()
        self.exportPnl.setLayout(None);
        self.exportPnl.setBounds(0, 0, 1000, 1000);
        self.exportPnl.add(exportLType)
        self.exportPnl.add(self.exportType)
        self.exportPnl.add(exportLES)
        self.exportPnl.add(self.exportES)
        self.exportPnl.add(self.exportButton)

    def initEnforcementDetector(self):
        #
        ## init enforcement detector tab
        #

        # These two variable appears to be unused...
        self.EDFP = ArrayList()
        self.EDCT = ArrayList()

        EDLType = JLabel("Type:")
        EDLType.setBounds(10, 10, 140, 30)

        EDLContent = JLabel("Content:")
        EDLContent.setBounds(10, 50, 140, 30)

        EDLabelList = JLabel("Filter List:")
        EDLabelList.setBounds(10, 165, 140, 30)

        EDStrings = ["Headers (simple string): (enforced message headers contains)", "Headers (regex): (enforced messege headers contains)", "Body (simple string): (enforced messege body contains)", "Body (regex): (enforced messege body contains)", "Full request (simple string): (enforced messege contains)", "Full request (regex): (enforced messege contains)", "Content-Length: (constant Content-Length number of enforced response)"]
        self.EDType = JComboBox(EDStrings)
        self.EDType.setBounds(80, 10, 430, 30)
       
        self.EDText = JTextArea("", 5, 30)
        self.EDText.setBounds(80, 50, 300, 110)

        self.EDModel = DefaultListModel();
        self.EDList = JList(self.EDModel);
        self.EDList.setBounds(80, 175, 300, 110)
        self.EDList.setBorder(LineBorder(Color.BLACK))

        self.EDAdd = JButton("Add filter",actionPerformed=self.addEDFilter)
        self.EDAdd.setBounds(390, 85, 120, 30)
        self.EDDel = JButton("Remove filter",actionPerformed=self.delEDFilter)
        self.EDDel.setBounds(390, 210, 120, 30)

        self.EDPnl = JPanel()
        self.EDPnl.setLayout(None);
        self.EDPnl.setBounds(0, 0, 1000, 1000);
        self.EDPnl.add(EDLType)
        self.EDPnl.add(self.EDType)
        self.EDPnl.add(EDLContent)
        self.EDPnl.add(self.EDText)
        self.EDPnl.add(self.EDAdd)
        self.EDPnl.add(self.EDDel)
        self.EDPnl.add(EDLabelList)
        self.EDPnl.add(self.EDList)

    def initEnforcementDetectorUnauthorized(self):
        #
        ## init enforcement detector tab
        #

        EDLType = JLabel("Type:")
        EDLType.setBounds(10, 10, 140, 30)

        EDLContent = JLabel("Content:")
        EDLContent.setBounds(10, 50, 140, 30)

        EDLabelList = JLabel("Filter List:")
        EDLabelList.setBounds(10, 165, 140, 30)

        EDStrings = ["Headers (simple string): (enforced message headers contains)", "Headers (regex): (enforced messege headers contains)", "Body (simple string): (enforced messege body contains)", "Body (regex): (enforced messege body contains)", "Full request (simple string): (enforced messege contains)", "Full request (regex): (enforced messege contains)", "Content-Length: (constant Content-Length number of enforced response)"]
        self.EDTypeUnauth = JComboBox(EDStrings)
        self.EDTypeUnauth.setBounds(80, 10, 430, 30)
       
        self.EDTextUnauth = JTextArea("", 5, 30)
        self.EDTextUnauth.setBounds(80, 50, 300, 110)

        self.EDModelUnauth = DefaultListModel();
        self.EDListUnauth = JList(self.EDModelUnauth);
        self.EDListUnauth.setBounds(80, 175, 300, 110)
        self.EDListUnauth.setBorder(LineBorder(Color.BLACK))

        self.EDAddUnauth = JButton("Add filter",actionPerformed=self.addEDFilterUnauth)
        self.EDAddUnauth.setBounds(390, 85, 120, 30)
        self.EDDelUnauth = JButton("Remove filter",actionPerformed=self.delEDFilterUnauth)
        self.EDDelUnauth.setBounds(390, 210, 120, 30)

        self.EDPnlUnauth = JPanel()
        self.EDPnlUnauth.setLayout(None);
        self.EDPnlUnauth.setBounds(0, 0, 1000, 1000);
        self.EDPnlUnauth.add(EDLType)
        self.EDPnlUnauth.add(self.EDTypeUnauth)
        self.EDPnlUnauth.add(EDLContent)
        self.EDPnlUnauth.add(self.EDTextUnauth)
        self.EDPnlUnauth.add(self.EDAddUnauth)
        self.EDPnlUnauth.add(self.EDDelUnauth)
        self.EDPnlUnauth.add(EDLabelList)
        self.EDPnlUnauth.add(self.EDListUnauth)        

    def initInterceptionFilters(self):
        #
        ##  init interception filters tab
        #

        IFStrings = ["Scope items only: (Content is not required)","URL Contains (simple string): ","URL Contains (regex): ","URL Not Contains (simple string): ","URL Not Contains (regex): "]
        self.IFType = JComboBox(IFStrings)
        self.IFType.setBounds(80, 10, 430, 30)
       
        self.IFModel = DefaultListModel();
        self.IFList = JList(self.IFModel);
        self.IFList.setBounds(80, 175, 300, 110)
        self.IFList.setBorder(LineBorder(Color.BLACK))

        self.IFText = JTextArea("", 5, 30)
        self.IFText.setBounds(80, 50, 300, 110)

        IFLType = JLabel("Type:")
        IFLType.setBounds(10, 10, 140, 30)

        IFLContent = JLabel("Content:")
        IFLContent.setBounds(10, 50, 140, 30)

        IFLabelList = JLabel("Filter List:")
        IFLabelList.setBounds(10, 165, 140, 30)

        self.IFAdd = JButton("Add filter",actionPerformed=self.addIFFilter)
        self.IFAdd.setBounds(390, 85, 120, 30)
        self.IFDel = JButton("Remove filter",actionPerformed=self.delIFFilter)
        self.IFDel.setBounds(390, 210, 120, 30)

        self.filtersPnl = JPanel()
        self.filtersPnl.setLayout(None);
        self.filtersPnl.setBounds(0, 0, 1000, 1000);
        self.filtersPnl.add(IFLType)
        self.filtersPnl.add(self.IFType)
        self.filtersPnl.add(IFLContent)
        self.filtersPnl.add(self.IFText)
        self.filtersPnl.add(self.IFAdd)
        self.filtersPnl.add(self.IFDel)
        self.filtersPnl.add(IFLabelList)
        self.filtersPnl.add(self.IFList)


    def initConfigurationTab(self):
        #
        ##  init configuration tab
        #
        self.prevent304 = JCheckBox("Prevent 304 Not Modified status code")
        self.prevent304.setBounds(290, 25, 300, 30)

        self.ignore304 = JCheckBox("Ignore 304/204 status code responses")
        self.ignore304.setBounds(290, 5, 300, 30)
        self.ignore304.setSelected(True)

        self.autoScroll = JCheckBox("Auto Scroll")
        #self.autoScroll.setBounds(290, 45, 140, 30)
        self.autoScroll.setBounds(160, 40, 140, 30)

        self.doUnauthorizedRequest = JCheckBox("Check unauthenticated")
        self.doUnauthorizedRequest.setBounds(290, 45, 300, 30)
        self.doUnauthorizedRequest.setSelected(True)

        startLabel = JLabel("Authorization checks:")
        startLabel.setBounds(10, 10, 140, 30)
        self.startButton = JButton("Autorize is off",actionPerformed=self.startOrStop)
        self.startButton.setBounds(160, 10, 120, 30)
        self.startButton.setBackground(Color(255, 100, 91, 255))

        self.clearButton = JButton("Clear List",actionPerformed=self.clearList)
        self.clearButton.setBounds(10, 40, 100, 30)

        self.replaceString = JTextArea("Cookie: Insert=injected; header=here;", 5, 30)
        self.replaceString.setWrapStyleWord(True);
        self.replaceString.setLineWrap(True)
        self.replaceString.setBounds(10, 80, 470, 180)

        self.filtersTabs = JTabbedPane()
        self.filtersTabs.addTab("Enforcement Detector", self.EDPnl)
        self.filtersTabs.addTab("Detector Unauthenticated", self.EDPnlUnauth)
        self.filtersTabs.addTab("Interception Filters", self.filtersPnl)
        self.filtersTabs.addTab("Export", self.exportPnl)

        self.filtersTabs.setBounds(0, 280, 2000, 700)

        self.pnl = JPanel()
        self.pnl.setBounds(0, 0, 1000, 1000);
        self.pnl.setLayout(None);
        self.pnl.add(self.startButton)
        self.pnl.add(self.clearButton)
        self.pnl.add(self.replaceString)
        self.pnl.add(startLabel)
        self.pnl.add(self.autoScroll)
        self.pnl.add(self.ignore304)
        self.pnl.add(self.prevent304)
        self.pnl.add(self.doUnauthorizedRequest)
        self.pnl.add(self.filtersTabs)

    def initTabs(self):
        #
        ##  init autorize tabs
        #
        
        self.logTable = Table(self)

        self.logTable.setAutoCreateRowSorter(True)        

        tableWidth = self.logTable.getPreferredSize().width        
        self.logTable.getColumn("ID").setPreferredWidth(Math.round(tableWidth / 50 * 2))
        self.logTable.getColumn("URL").setPreferredWidth(Math.round(tableWidth / 50 * 24))
        self.logTable.getColumn("Orig. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4))
        self.logTable.getColumn("Modif. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4))
        self.logTable.getColumn("Unauth. Length").setPreferredWidth(Math.round(tableWidth / 50 * 4))
        self.logTable.getColumn("Authorization Enforcement Status").setPreferredWidth(Math.round(tableWidth / 50 * 4))
        self.logTable.getColumn("Authorization Unauth. Status").setPreferredWidth(Math.round(tableWidth / 50 * 4))

        self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT)
        self._splitpane.setResizeWeight(1)
        self.scrollPane = JScrollPane(self.logTable)
        self._splitpane.setLeftComponent(self.scrollPane)
        self.scrollPane.getVerticalScrollBar().addAdjustmentListener(autoScrollListener(self))
        self.menuES0 = JCheckBoxMenuItem(self._enfocementStatuses[0],True)
        self.menuES1 = JCheckBoxMenuItem(self._enfocementStatuses[1],True)
        self.menuES2 = JCheckBoxMenuItem(self._enfocementStatuses[2],True)
        self.menuES0.addItemListener(menuTableFilter(self))
        self.menuES1.addItemListener(menuTableFilter(self))
        self.menuES2.addItemListener(menuTableFilter(self))

        copyURLitem = JMenuItem("Copy URL");
        copyURLitem.addActionListener(copySelectedURL(self))
        self.menu = JPopupMenu("Popup")
        self.menu.add(copyURLitem)
        self.menu.add(self.menuES0)
        self.menu.add(self.menuES1)
        self.menu.add(self.menuES2)

        self.tabs = JTabbedPane()
        self._requestViewer = self._callbacks.createMessageEditor(self, False)
        self._responseViewer = self._callbacks.createMessageEditor(self, False)

        self._originalrequestViewer = self._callbacks.createMessageEditor(self, False)
        self._originalresponseViewer = self._callbacks.createMessageEditor(self, False)

        self._unauthorizedrequestViewer = self._callbacks.createMessageEditor(self, False)
        self._unauthorizedresponseViewer = self._callbacks.createMessageEditor(self, False)        

        self.tabs.addTab("Modified Request", self._requestViewer.getComponent())
        self.tabs.addTab("Modified Response", self._responseViewer.getComponent())

        self.tabs.addTab("Original Request", self._originalrequestViewer.getComponent())
        self.tabs.addTab("Original Response", self._originalresponseViewer.getComponent())

        self.tabs.addTab("Unauthenticated Request", self._unauthorizedrequestViewer.getComponent())
        self.tabs.addTab("Unauthenticated Response", self._unauthorizedresponseViewer.getComponent())        

        self.tabs.addTab("Configuration", self.pnl)
        self.tabs.setSelectedIndex(6)
        self._splitpane.setRightComponent(self.tabs)

    def initCallbacks(self):
        #
        ##  init callbacks
        #

        # customize our UI components
        self._callbacks.customizeUiComponent(self._splitpane)
        self._callbacks.customizeUiComponent(self.logTable)
        self._callbacks.customizeUiComponent(self.scrollPane)
        self._callbacks.customizeUiComponent(self.tabs)
        self._callbacks.customizeUiComponent(self.filtersTabs)
        self._callbacks.registerContextMenuFactory(self)
        # add the custom tab to Burp's UI
        self._callbacks.addSuiteTab(self)


    #
    ## Events functions
    #
    def startOrStop(self, event):
        if self.startButton.getText() == "Autorize is off":
            self.startButton.setText("Autorize is on")
            self.startButton.setBackground(Color.GREEN)
            self.intercept = 1
            self._callbacks.registerHttpListener(self)
        else:
            self.startButton.setText("Autorize is off")
            self.startButton.setBackground(Color(255, 100, 91, 255))
            self.intercept = 0
            self._callbacks.removeHttpListener(self)

    def addEDFilter(self, event):
        typeName = self.EDType.getSelectedItem().split(":")[0]
        self.EDModel.addElement(typeName + ": " + self.EDText.getText())

    def delEDFilter(self, event):
        index = self.EDList.getSelectedIndex();
        if not index == -1:
            self.EDModel.remove(index);

    def addEDFilterUnauth(self, event):
        typeName = self.EDTypeUnauth.getSelectedItem().split(":")[0]
        self.EDModelUnauth.addElement(typeName + ": " + self.EDTextUnauth.getText())

    def delEDFilterUnauth(self, event):
        index = self.EDListUnauth.getSelectedIndex();
        if not index == -1:
            self.EDModelUnauth.remove(index);            

    def addIFFilter(self, event):
        typeName = self.IFType.getSelectedItem().split(":")[0]
        self.IFModel.addElement(typeName + ": " + self.IFText.getText())

    def delIFFilter(self, event):
        index = self.IFList.getSelectedIndex();
        if not index == -1:
            self.IFModel.remove(index);

    def clearList(self, event):
        self._lock.acquire()
        oldSize = self._log.size()
        self._log.clear()
        self.fireTableRowsDeleted(0, oldSize - 1)
        self._lock.release()

    def export(self, event):
        if self.exportType.getSelectedItem() == "HTML":
            self.exportToHTML()
        else:
            self.exportToCSV()

    def exportToCSV(self):
        parentFrame = JFrame()
        fileChooser = JFileChooser()
        fileChooser.setSelectedFile(File("AutorizeReprort.csv"));
        fileChooser.setDialogTitle("Save Autorize Report")
        userSelection = fileChooser.showSaveDialog(parentFrame)
        if userSelection == JFileChooser.APPROVE_OPTION:
            fileToSave = fileChooser.getSelectedFile()

        enforcementStatusFilter = self.exportES.getSelectedItem()
        csvContent = "id\tURL\tOriginal length\tModified length\tUnauthorized length\tAuthorization Enforcement Status\tAuthorization Unauthenticated Status\n"

        for i in range(0,self._log.size()):

            if enforcementStatusFilter == "All Statuses":
                csvContent += "%d\t%s\t%d\t%d\t%d\t%s\t%s\n" % (self._log.get(i)._id,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, self._log.get(i)._enfocementStatus, self._log.get(i)._enfocementStatusUnauthorized)
                
            else:
                if (enforcementStatusFilter == self._log.get(i)._enfocementStatus) or (enforcementStatusFilter == self._log.get(i)._enfocementStatusUnauthorized):
                    csvContent += "%d\t%s\t%d\t%d\t%d\t%s\t%s\n" % (self._log.get(i)._id,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, self._log.get(i)._enfocementStatus, self._log.get(i)._enfocementStatusUnauthorized)
        
        f = open(fileToSave.getAbsolutePath(), 'w')
        f.writelines(csvContent)
        f.close()


    def exportToHTML(self):
        parentFrame = JFrame()
        fileChooser = JFileChooser()
        fileChooser.setSelectedFile(File("AutorizeReprort.html"));
        fileChooser.setDialogTitle("Save Autorize Report")
        userSelection = fileChooser.showSaveDialog(parentFrame)
        if userSelection == JFileChooser.APPROVE_OPTION:
            fileToSave = fileChooser.getSelectedFile()

        enforcementStatusFilter = self.exportES.getSelectedItem()
        htmlContent = """<html><title>Autorize Report by Barak Tawily</title>
        <style>
        .datagrid table { border-collapse: collapse; text-align: left; width: 100%; }
         .datagrid {font: normal 12px/150% Arial, Helvetica, sans-serif; background: #fff; overflow: hidden; border: 1px solid #006699; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; }
         .datagrid table td, .datagrid table th { padding: 3px 10px; }
         .datagrid table thead th {background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; color:#FFFFFF; font-size: 15px; font-weight: bold; border-left: 1px solid #0070A8; } .datagrid table thead th:first-child { border: none; }.datagrid table tbody td { color: #00496B; border-left: 1px solid #E1EEF4;font-size: 12px;font-weight: normal; }.datagrid table tbody .alt td { background: #E1EEF4; color: #00496B; }.datagrid table tbody td:first-child { border-left: none; }.datagrid table tbody tr:last-child td { border-bottom: none; }.datagrid table tfoot td div { border-top: 1px solid #006699;background: #E1EEF4;} .datagrid table tfoot td { padding: 0; font-size: 12px } .datagrid table tfoot td div{ padding: 2px; }.datagrid table tfoot td ul { margin: 0; padding:0; list-style: none; text-align: right; }.datagrid table tfoot  li { display: inline; }.datagrid table tfoot li a { text-decoration: none; display: inline-block;  padding: 2px 8px; margin: 1px;color: #FFFFFF;border: 1px solid #006699;-webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #006699), color-stop(1, #00557F) );background:-moz-linear-gradient( center top, #006699 5%, #00557F 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699', endColorstr='#00557F');background-color:#006699; }.datagrid table tfoot ul.active, .datagrid table tfoot ul a:hover { text-decoration: none;border-color: #006699; color: #FFFFFF; background: none; background-color:#00557F;}div.dhtmlx_window_active, div.dhx_modal_cover_dv { position: fixed !important; }
        table {
        width: 100%;
        table-layout: fixed;
        }
        td {
            border: 1px solid #35f;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        td.a {
            width: 13%;
            white-space: nowrap;
        }
        td.b {
            width: 9%;
            word-wrap: break-word;
        }
        </style>
        <body>
        <h1>Autorize Report<h1>
        <div class="datagrid"><table>
        <thead><tr><th width=\"3%\">ID</th><th width=\"48%\">URL</th><th width=\"9%\">Original length</th><th width=\"9%\">Modified length</th><th width=\"9%\">Unauthorized length</th><th width=\"11%\">Authorization Enforcement Status</th><th width=\"11%\">Authorization Unauthenticated Status</th></tr></thead>
        <tbody>"""

        for i in range(0,self._log.size()):
            color_modified = ""
            if self._log.get(i)._enfocementStatus == self._enfocementStatuses[0]:
                color_modified = "red"
            if self._log.get(i)._enfocementStatus == self._enfocementStatuses[1]:
                color_modified = "yellow"
            if self._log.get(i)._enfocementStatus == self._enfocementStatuses[2]:
                color_modified = "LawnGreen"

            color_unauthorized = ""
            if self._log.get(i)._enfocementStatusUnauthorized == self._enfocementStatuses[0]:
                color_unauthorized = "red"
            if self._log.get(i)._enfocementStatusUnauthorized == self._enfocementStatuses[1]:
                color_unauthorized = "yellow"
            if self._log.get(i)._enfocementStatusUnauthorized == self._enfocementStatuses[2]:
                color_unauthorized = "LawnGreen"

            if enforcementStatusFilter == "All Statuses":
                htmlContent += "<tr><td>%d</td><td><a href=\"%s\">%s</a></td><td>%d</td><td>%d</td><td>%d</td><td bgcolor=\"%s\">%s</td><td bgcolor=\"%s\">%s</td></tr>" % (self._log.get(i)._id,self._log.get(i)._url,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, color_modified, self._log.get(i)._enfocementStatus, color_unauthorized, self._log.get(i)._enfocementStatusUnauthorized)
            else:
                if (enforcementStatusFilter == self._log.get(i)._enfocementStatus) or (enforcementStatusFilter == self._log.get(i)._enfocementStatusUnauthorized):
                    htmlContent += "<tr><td>%d</td><td><a href=\"%s\">%s</a></td><td>%d</td><td>%d</td><td>%d</td><td bgcolor=\"%s\">%s</td><td bgcolor=\"%s\">%s</td></tr>" % (self._log.get(i)._id,self._log.get(i)._url,self._log.get(i)._url, len(self._log.get(i)._originalrequestResponse.getResponse()) if self._log.get(i)._originalrequestResponse != None else 0, len(self._log.get(i)._requestResponse.getResponse()) if self._log.get(i)._requestResponse != None else 0, len(self._log.get(i)._unauthorizedRequestResponse.getResponse()) if self._log.get(i)._unauthorizedRequestResponse != None else 0, color_modified, self._log.get(i)._enfocementStatus, color_unauthorized, self._log.get(i)._enfocementStatusUnauthorized)

        htmlContent += "</tbody></table></div></body></html>"
        f = open(fileToSave.getAbsolutePath(), 'w')
        f.writelines(htmlContent)
        f.close()




    #
    # implement IContextMenuFactory
    #
    def createMenuItems(self, invocation):
        responses = invocation.getSelectedMessages();
        if responses > 0:
            ret = LinkedList()
            requestMenuItem = JMenuItem("Send request to Autorize");
            cookieMenuItem = JMenuItem("Send cookie to Autorize");
            requestMenuItem.addActionListener(handleMenuItems(self,responses[0], "request"))
            cookieMenuItem.addActionListener(handleMenuItems(self, responses[0], "cookie"))   
            ret.add(requestMenuItem);
            ret.add(cookieMenuItem);
            return(ret);
        return null;


    #
    # implement ITab
    #
    def getTabCaption(self):
        return "Autorize"
    
    def getUiComponent(self):
        return self._splitpane
        
    #
    # extend AbstractTableModel
    #
    
    def getRowCount(self):
        try:
            return self._log.size()
        except:
            return 0

    def getColumnCount(self):
        return 7

    def getColumnName(self, columnIndex):
        if columnIndex == 0:
            return "ID"
        if columnIndex == 1:
            return "URL"
        if columnIndex == 2:
            return "Orig. Length"            
        if columnIndex == 3:
            return "Modif. Length" 
        if columnIndex == 4:
            return "Unauth. Length"           
        if columnIndex == 5:
            return "Authorization Enforcement Status"
        if columnIndex == 6:
            return "Authorization Unauth. Status"
        return ""

    def getColumnClass(self, columnIndex):
        if columnIndex == 0:
            return Integer
        if columnIndex == 1:
            return String
        if columnIndex == 2:
            return Integer           
        if columnIndex == 3:
            return Integer 
        if columnIndex == 4:
            return Integer          
        if columnIndex == 5:
            return String
        if columnIndex == 6:
            return String
        return String

    def getValueAt(self, rowIndex, columnIndex):
        logEntry = self._log.get(rowIndex)
        if columnIndex == 0:
            return logEntry._id
        if columnIndex == 1:
            return logEntry._url.toString()
        if columnIndex == 2:
            return len(logEntry._originalrequestResponse.getResponse())
        if columnIndex == 3:
            return len(logEntry._requestResponse.getResponse())
        if columnIndex == 4:
            if logEntry._unauthorizedRequestResponse != None:
                return len(logEntry._unauthorizedRequestResponse.getResponse())
            else:
                #return "-"
                return 0
        if columnIndex == 5:
            return logEntry._enfocementStatus   
        if columnIndex == 6:
            return logEntry._enfocementStatusUnauthorized        
        return ""

    #
    # implement IMessageEditorController
    # this allows our request/response viewers to obtain details about the messages being displayed
    #
    
    def getHttpService(self):
        return self._currentlyDisplayedItem.getHttpService()

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

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


    #
    # implement IHttpListener
    #
    def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):

        #if (self.intercept == 1) and (toolFlag != self._callbacks.TOOL_EXTENDER):
        if (self.intercept == 1) and (toolFlag == self._callbacks.TOOL_PROXY):
            if self.prevent304.isSelected():
                if messageIsRequest:
                    requestHeaders = list(self._helpers.analyzeRequest(messageInfo).getHeaders())
                    newHeaders = list()
                    found = 0
                    for header in requestHeaders:
                        if not "If-None-Match:" in header and not "If-Modified-Since:" in header:
                            newHeaders.append(header)
                            found = 1
                    if found == 1:
                        requestInfo = self._helpers.analyzeRequest(messageInfo)
                        bodyBytes = messageInfo.getRequest()[requestInfo.getBodyOffset():]
                        bodyStr = self._helpers.bytesToString(bodyBytes)
                        messageInfo.setRequest(self._helpers.buildHttpMessage(newHeaders, bodyStr))


            if not messageIsRequest:
                if not self.replaceString.getText() in self._helpers.analyzeRequest(messageInfo).getHeaders():
                    if self.ignore304.isSelected():
                        firstHeader = self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders()[0]
                        if "304" in firstHeader or "204" in firstHeader:
                           return
                    if self.IFList.getModel().getSize() == 0:
                        self.checkAuthorization(messageInfo,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected())
                    else:
                        urlString = str(self._helpers.analyzeRequest(messageInfo).getUrl())
                        
                        do_the_check = 1

                        for i in range(0,self.IFList.getModel().getSize()):

                            if self.IFList.getModel().getElementAt(i).split(":")[0] == "Scope items only":
                                currentURL = URL(urlString)
                                if not self._callbacks.isInScope(currentURL):
                                    do_the_check = 0
                            if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Contains (simple string)":
                                if self.IFList.getModel().getElementAt(i)[30:] not in urlString:
                                    do_the_check = 0
                            if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Contains (regex)":
                                regex_string = self.IFList.getModel().getElementAt(i)[22:]
                                p = re.compile(regex_string, re.IGNORECASE)
                                if not p.search(urlString):
                                    do_the_check = 0  
                            if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Not Contains (simple string)":
                                if self.IFList.getModel().getElementAt(i)[34:] in urlString:
                                    do_the_check = 0
                            if self.IFList.getModel().getElementAt(i).split(":")[0] == "URL Not Contains (regex)":
                                regex_string = self.IFList.getModel().getElementAt(i)[26:]
                                p = re.compile(regex_string, re.IGNORECASE)
                                if p.search(urlString):
                                    do_the_check = 0                                                                       

                        if do_the_check:
                            self.checkAuthorization(messageInfo,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected())

        return

    def sendRequestToAutorizeWork(self,messageInfo):

        if messageInfo.getResponse() == None:
            message = self.makeMessage(messageInfo,False,False)
            requestResponse = self.makeRequest(messageInfo, message)
            self.checkAuthorization(requestResponse,self._helpers.analyzeResponse(requestResponse.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected())
        else:
            self.checkAuthorization(messageInfo,self._helpers.analyzeResponse(messageInfo.getResponse()).getHeaders(),self.doUnauthorizedRequest.isSelected())


    def makeRequest(self, messageInfo, message):
        requestURL = self._helpers.analyzeRequest(messageInfo).getUrl()
        return self._callbacks.makeHttpRequest(self._helpers.buildHttpService(str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https"), message)

    def makeMessage(self, messageInfo, removeOrNot, authorizeOrNot):
        requestInfo = self._helpers.analyzeRequest(messageInfo)
        headers = requestInfo.getHeaders()
        if removeOrNot:
            headers = list(headers)
            removeHeaders = ArrayList()
            removeHeaders.add(self.replaceString.getText()[0:self.replaceString.getText().index(":")])

            for header in headers[:]:
                for removeHeader in removeHeaders:
                    if removeHeader in header:
                        headers.remove(header)

            if authorizeOrNot:
                headers.append(self.replaceString.getText())

        msgBody = messageInfo.getRequest()[requestInfo.getBodyOffset():]
        return self._helpers.buildHttpMessage(headers, msgBody)

    def checkBypass(self,oldStatusCode,newStatusCode,oldContentLen,newContentLen,filters,requestResponse):

        analyzedResponse = self._helpers.analyzeResponse(requestResponse.getResponse())
        impression = ""

        if oldStatusCode == newStatusCode:
            if oldContentLen == newContentLen:
                impression = self._enfocementStatuses[0]
            else:

                auth_enforced = 1
                
                for filter in filters:

                    if str(filter).startswith("Headers (simple string): "):
                        if not(filter[25:] in self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])):
                            auth_enforced = 0

                    if str(filter).startswith("Headers (regex): "):
                        regex_string = filter[17:]
                        p = re.compile(regex_string, re.IGNORECASE)
                        if not p.search(self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])):
                            auth_enforced = 0

                    if str(filter).startswith("Body (simple string): "):
                        if not(filter[22:] in self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])):
                            auth_enforced = 0

                    if str(filter).startswith("Body (regex): "):
                        regex_string = filter[14:]
                        p = re.compile(regex_string, re.IGNORECASE)
                        if not p.search(self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])):
                            auth_enforced = 0

                    if str(filter).startswith("Full request (simple string): "):
                        if not(filter[30:] in self._helpers.bytesToString(requestResponse.getResponse())):
                            auth_enforced = 0

                    if str(filter).startswith("Full request (regex): "):
                        regex_string = filter[22:]
                        p = re.compile(regex_string, re.IGNORECASE)
                        if not p.search(self._helpers.bytesToString(requestResponse.getResponse())):
                            auth_enforced = 0

                    if str(filter).startswith("Content-Length: "):
                        if newContentLen != filter:
                            auth_enforced = 0
                
                if auth_enforced:
                    impression = self._enfocementStatuses[2]
                else:
                    impression = self._enfocementStatuses[1]
                         
        else:
            impression = self._enfocementStatuses[2]

        return impression

    def checkAuthorization(self, messageInfo, originalHeaders, checkUnauthorized):
        message = self.makeMessage(messageInfo,True,True)
        requestResponse = self.makeRequest(messageInfo, message)
        analyzedResponse = self._helpers.analyzeResponse(requestResponse.getResponse())
        
        oldStatusCode = originalHeaders[0]
        newStatusCode = analyzedResponse.getHeaders()[0]
        oldContentLen = self.getContentLength(originalHeaders)
        newContentLen = self.getContentLength(analyzedResponse.getHeaders())

        # Check unauthorized request
        if checkUnauthorized:
            messageUnauthorized = self.makeMessage(messageInfo,True,False)
            requestResponseUnauthorized = self.makeRequest(messageInfo, messageUnauthorized)
            analyzedResponseUnauthorized = self._helpers.analyzeResponse(requestResponseUnauthorized.getResponse())  
            statusCodeUnauthorized = analyzedResponseUnauthorized.getHeaders()[0]
            contentLenUnauthorized = self.getContentLength(analyzedResponseUnauthorized.getHeaders())

        EDFilters = self.EDModel.toArray()
        impression = self.checkBypass(oldStatusCode,newStatusCode,oldContentLen,newContentLen,EDFilters,requestResponse)

        if checkUnauthorized:
            EDFiltersUnauth = self.EDModelUnauth.toArray()
            impressionUnauthorized = self.checkBypass(oldStatusCode,statusCodeUnauthorized,oldContentLen,contentLenUnauthorized,EDFiltersUnauth,requestResponseUnauthorized)

        self._lock.acquire()
        
        row = self._log.size()
        
        if checkUnauthorized:
            self._log.add(LogEntry(self.currentRequestNumber,self._callbacks.saveBuffersToTempFiles(requestResponse), self._helpers.analyzeRequest(requestResponse).getUrl(),messageInfo,impression,self._callbacks.saveBuffersToTempFiles(requestResponseUnauthorized),impressionUnauthorized)) # same requests not include again.
        else:
            self._log.add(LogEntry(self.currentRequestNumber,self._callbacks.saveBuffersToTempFiles(requestResponse), self._helpers.analyzeRequest(requestResponse).getUrl(),messageInfo,impression,None,"Disabled")) # same requests not include again.
        
        self.fireTableRowsInserted(row, row)
        self.currentRequestNumber = self.currentRequestNumber + 1
        self._lock.release()
        
    def getContentLength(self, analyzedResponseHeaders):
        for header in analyzedResponseHeaders:
            if "Content-Length:" in header:
                return header;
        return "null"

    def getCookieFromMessage(self, messageInfo):
        headers = list(self._helpers.analyzeRequest(messageInfo.getRequest()).getHeaders())
        for header in headers:
            if "Cookie:" in header:
                return header
        return None
Esempio n. 26
0
class BurpExtender(IBurpExtender, ITab, IContextMenuFactory):

    #
    # implement IBurpExtender
    #

    def registerExtenderCallbacks(self, callbacks):
        
        # properties
        self._title = "Generate Python Template"
        self._templatePath = '###### ----> PUT HERE THE ABSOLUTE PATH TO template.py <--- ####'
        
        # set our extension name
        callbacks.setExtensionName(self._title)
        
        # keep a reference to our callbacks object
        self._callbacks = callbacks
        
        # obtain an extension helpers object
        self._helpers = callbacks.getHelpers()
        
        # obtain std streams
        self._stdout = PrintWriter(callbacks.getStdout(), True)
        self._stderr = PrintWriter(callbacks.getStderr(), True)
                
        # main pane (top/bottom)
        self._mainpane = JPanel()
        self._mainpane.setLayout( GridLayout(2,1) )
        
        # configure bottom pane for buttons
        self._botPane = JPanel()
        flowLayout = FlowLayout()
        self._botPane.setLayout( flowLayout )
        self._botPane.add( JButton("Generate", actionPerformed=self.regeneratePy) )
        self._botPane.add( JButton("Export", actionPerformed=self.exportPy) )
        
        # Configure pyViewer (JTextArea) for python output --> top pane
        self._pyViewer = JTextArea(5, 20);
        scrollPane = JScrollPane(self._pyViewer); 
        self._pyViewer.setEditable(True);
        self._pyViewer.setText( "Waiting request ..." );
        
        ### Assign top / bottom components
        self._mainpane.add(scrollPane)
        self._mainpane.add(self._botPane)
                
        # customize our UI components
        callbacks.customizeUiComponent(self._mainpane)
        
        # add the custom tab to Burp's UI
        callbacks.addSuiteTab(self)
        
        
        # register ourselves as a ContextMenuFactory
        callbacks.registerContextMenuFactory(self)
        
        return

    def regeneratePy(self,event):
        pass

    def exportPy(self,event):
        chooseFile = JFileChooser()
        ret = chooseFile.showDialog(self._mainpane, "Choose file")
        filename = chooseFile.getSelectedFile().getCanonicalPath()
        self._stdout.println("Export to : " + filename )
        open(filename, 'w', 0).write( self._pyViewer.getText() )


    #
    # implement ITab
    #
    
    def getTabCaption(self):
        return "PyTemplate"
    
    def getUiComponent(self):
        return self._mainpane


    #
    # implement IContextMenuFactory
    #

    def createMenuItems(self, invocation):
        # add a new item executing our action
        item = JMenuItem(self._title, actionPerformed=lambda x, inv=invocation: self.loadRequest(inv))
        return [ item ]

    def loadRequest(self, invocation):
        pyCode = self.pythonHeader()
        selectedMessages = invocation.getSelectedMessages()
        self._numbMessages = len(selectedMessages)
        self._currentMessageNumber = 1
        for message in selectedMessages:
            self._currentlyDisplayedItem = message
            pyCode += self.generateRequest()
            self._currentMessageNumber += 1
        pyCode += '\n' + self.generateMain()
        self._pyViewer.setText( pyCode );


    def pythonHeader(self):
        pyCode = "# -*- coding: utf-8 -*-\n\n"
        pyCode += "import requests\n"
        pyCode += "import time\n\n"
        return pyCode

    def formatHeaders(self, httpReqInfos):
        headers = httpReqInfos.getHeaders()[1:] #First header is method+path : GET/POST ..
        formatHeaders = ""

        name,content = headers[0].split(':', 1)
        formatHeaders += 'headers["' + self.sanitizeStr(name) + '"] = ' + '"' + self.sanitizeStr(content) + '"\n'

        for header in headers[1:]:
            name,content = header.split(':', 1)
            if "Content-Length" not in name:
                if "Cookie" in name and self._numbMessages > 1 and self._currentMessageNumber != 1:
                    continue
                else:
                    formatHeaders += '    headers["' + self.sanitizeStr(name) + '"] = ' + '"' + self.sanitizeStr(content) + '"\n'
        return formatHeaders


    def sanitizeStr(self, strToValid):
        valid = str(strToValid)
        valid = valid.replace('"','\\"')
        return valid.strip()

    def generateRequest(self):
        httpInfos = self._currentlyDisplayedItem.getHttpService()
        httpReq = self._currentlyDisplayedItem.getRequest()
        requestInfos = self._helpers.analyzeRequest(httpInfos, httpReq)
        pyTemplate = open(self._templatePath, 'r').read()
        pyCode = pyTemplate.replace( '$$NUM$$', str(self._currentMessageNumber) )
        pyCode = pyCode.replace( '$$URL$$', self.sanitizeStr(requestInfos.getUrl()) )
        pyCode = pyCode.replace( '$$HEADERS$$', self.formatHeaders(requestInfos) )
        pyCode = pyCode.replace( '$$METHOD$$', requestInfos.getMethod() )
        if requestInfos.getMethod() == "GET":
            trigger = "req = session.get(url, headers=headers, verify=False, allow_redirects=True)" 
            pyCode = pyCode.replace( '$$TRIGGER$$', trigger )
            pyCode = pyCode.replace( '$$POST_DATA$$', '' )
        if requestInfos.getMethod() == "POST":
            trigger = "req = session.post(url, headers=headers, data=post_data, verify=False, allow_redirects=True)" 
            pyCode = pyCode.replace( '$$TRIGGER$$', trigger )
            rawData = httpReq[requestInfos.getBodyOffset():].tostring()
            dataPyCode = '## POST DATA\n'
            dataPyCode += '    post_data = "' + self.sanitizeStr(rawData) + '"\n'
            pyCode = pyCode.replace( '$$POST_DATA$$', dataPyCode )
        return pyCode + '\n'

    def generateMain(self):
        pyCode = 'if __name__ == "__main__":\n'
        pyCode += '    session = requests.Session()\n'
        for i in xrange(1, self._numbMessages + 1):
            pyCode += '    code_'+str(i)+', time_'+str(i)+', response_'+str(i)+' = performRequest_'+str(i)+'(session)\n'
        return pyCode
Esempio n. 27
0
class BurpExtender(IBurpExtender, ITab, IHttpListener,
                   IMessageEditorController, AbstractTableModel,
                   IContextMenuFactory):
    def registerExtenderCallbacks(self, callbacks):
        # smart xss feature (print conclusion and observation)
        # mark resulsts
        # add automatic check pages in the same domain

        self.tagPayloads = [
            "<b>test", "<b onmouseover=test()>test",
            "<img src=err onerror=test()>", "<script>test</script>"
            "", "<scr ipt>test</scr ipt>", "<SCRIPT>test;</SCRIPT>",
            "<scri<script>pt>test;</scr</script>ipt>",
            "<SCRI<script>PT>test;</SCR</script>IPT>",
            "<scri<scr<script>ipt>pt>test;</scr</sc</script>ript>ipt>",
            "<IMG \"\"\"><SCRIPT>test</SCRIPT>\">",
            "<IMG '''><SCRIPT>test</SCRIPT>'>", "<SCR%00IPT>test</SCR%00IPT>",
            "<IFRAME SRC='f' onerror=\"test\"></IFRAME>",
            "<IFRAME SRC='f' onerror='test'></IFRAME>",
            "<<SCRIPT>test//<</SCRIPT>", "<img src=\"1\" onerror=\"test\">",
            "<img src='1' onerror='test'",
            "<STYLE TYPE=\"text/javascript\">test;</STYLE>",
            "<<SCRIPT>test//<</SCRIPT>"
        ]
        self.attributePayloads = [
            "\"\"\"><SCRIPT>test", "'''><SCRIPT>test'",
            "\"><script>test</script>", "\"><script>test</script><\"",
            "'><script>test</script>", "'><script>test</script><'",
            "\";test;\"", "';test;'", ";test;", "\";test;//",
            "\"onmouseover=test ", "onerror=\"test\"", "onerror='test'",
            "onload=\"test\"", "onload='test'"
        ]
        self.xssKey = 'xssme'
        # keep a reference to our callbacks object
        self._callbacks = callbacks

        # obtain an extension helpers object
        self._helpers = callbacks.getHelpers()

        # set our extension name
        callbacks.setExtensionName("XSSor")

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

        # main split pane
        self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT)

        # table of log entries
        logTable = Table(self)
        scrollPane = JScrollPane(logTable)
        self._splitpane.setLeftComponent(scrollPane)

        # tabs with request/response viewers
        tabs = JTabbedPane()
        self._requestViewer = callbacks.createMessageEditor(self, False)
        self._responseViewer = callbacks.createMessageEditor(self, False)
        tabs.addTab("Request", self._requestViewer.getComponent())
        tabs.addTab("Response", self._responseViewer.getComponent())

        clearAPListBtn = JButton("Clear List",
                                 actionPerformed=self.clearAPList)
        clearAPListBtn.setBounds(10, 85, 120, 30)
        apListLabel = JLabel('Affected Pages List:')
        apListLabel.setBounds(10, 10, 140, 30)
        self.affectedModel = DefaultListModel()
        self.affectedList = JList(self.affectedModel)
        self.affectedList.addListSelectionListener(listSelectedChange(self))
        scrollAList = JScrollPane(self.affectedList)
        scrollAList.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        scrollAList.setBounds(150, 10, 550, 200)
        scrollAList.setBorder(LineBorder(Color.BLACK))

        APtabs = JTabbedPane()
        self._requestAPViewer = callbacks.createMessageEditor(self, False)
        self._responseAPViewer = callbacks.createMessageEditor(self, False)
        APtabs.addTab("Request", self._requestAPViewer.getComponent())
        APtabs.addTab("Affeced Page Response",
                      self._responseAPViewer.getComponent())
        APtabs.setBounds(0, 250, 700, 350)
        APtabs.setSelectedIndex(1)

        self.APpnl = JPanel()
        self.APpnl.setBounds(0, 0, 1000, 1000)
        self.APpnl.setLayout(None)
        self.APpnl.add(scrollAList)
        self.APpnl.add(clearAPListBtn)
        self.APpnl.add(APtabs)
        self.APpnl.add(apListLabel)
        tabs.addTab("Affected Pages", self.APpnl)
        self.intercept = 0

        ## init conf panel
        startLabel = JLabel("Plugin status:")
        startLabel.setBounds(10, 10, 140, 30)

        payloadLabel = JLabel("Basic Payload:")
        payloadLabel.setBounds(10, 50, 140, 30)

        self.basicPayload = "<script>alert(1)</script>"
        self.basicPayloadTxt = JTextArea(self.basicPayload, 5, 30)
        self.basicPayloadTxt.setBounds(120, 50, 305, 30)

        self.bruteForceMode = JCheckBox("Brute Force Mode")
        self.bruteForceMode.setBounds(120, 80, 300, 30)
        self.bruteForceMode.addItemListener(handleBFModeChange(self))

        self.tagPayloadsCheck = JCheckBox("Tag paylods")
        self.tagPayloadsCheck.setBounds(120, 100, 300, 30)
        self.tagPayloadsCheck.setSelected(True)
        self.tagPayloadsCheck.setEnabled(False)
        self.tagPayloadsCheck.addItemListener(handleBFModeList(self))

        self.attributePayloadsCheck = JCheckBox("Attribute payloads")
        self.attributePayloadsCheck.setBounds(260, 100, 300, 30)
        self.attributePayloadsCheck.setSelected(True)
        self.attributePayloadsCheck.setEnabled(False)
        self.attributePayloadsCheck.addItemListener(handleBFModeList(self))

        payloadListLabel = JLabel("Payloads list (for BF mode):")
        payloadListLabel.setBounds(10, 130, 140, 30)

        self.payloadsModel = DefaultListModel()
        self.payloadsList = JList(self.payloadsModel)
        scrollPayloadsList = JScrollPane(self.payloadsList)
        scrollPayloadsList.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        scrollPayloadsList.setBounds(120, 170, 300, 200)
        scrollPayloadsList.setBorder(LineBorder(
            Color.BLACK))  # add buttons to remove payloads and add

        for payload in self.tagPayloads:
            self.payloadsModel.addElement(payload)

        for payload in self.attributePayloads:
            self.payloadsModel.addElement(payload)

        self.startButton = JButton("XSSor is off",
                                   actionPerformed=self.startOrStop)
        self.startButton.setBounds(120, 10, 120, 30)
        self.startButton.setBackground(Color(255, 100, 91, 255))

        consoleTab = JTabbedPane()
        self.consoleLog = JTextArea("", 5, 30)
        scrollLog = JScrollPane(self.consoleLog)
        scrollLog.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        scrollLog.setBounds(120, 170, 550, 200)
        scrollLog.setBorder(LineBorder(Color.BLACK))
        scrollLog.getVerticalScrollBar().addAdjustmentListener(
            autoScrollListener(self))
        consoleTab.addTab("Console", scrollLog)
        consoleTab.setBounds(0, 400, 500, 200)

        self.pnl = JPanel()
        self.pnl.setBounds(0, 0, 1000, 1000)
        self.pnl.setLayout(None)
        self.pnl.add(self.startButton)
        self.pnl.add(startLabel)
        self.pnl.add(payloadLabel)
        self.pnl.add(self.basicPayloadTxt)
        self.pnl.add(self.bruteForceMode)
        self.pnl.add(payloadListLabel)
        self.pnl.add(scrollPayloadsList)
        self.pnl.add(self.attributePayloadsCheck)
        self.pnl.add(self.tagPayloadsCheck)
        self.pnl.add(consoleTab)

        tabs.addTab("Configuration", self.pnl)
        tabs.setSelectedIndex(3)
        self._splitpane.setRightComponent(tabs)

        # customize our UI components
        callbacks.customizeUiComponent(self._splitpane)
        callbacks.customizeUiComponent(logTable)
        callbacks.customizeUiComponent(scrollPane)
        callbacks.customizeUiComponent(tabs)

        # add the custom tab to Burp's UI
        callbacks.addSuiteTab(self)

        # register ourselves as an HTTP listener
        callbacks.registerHttpListener(self)
        self._callbacks.registerContextMenuFactory(self)

        print "Thank you for installing XSSor v0.1 extension"
        print "Created by Barak Tawily"
        print "\nGithub:\nhttps://github.com/Quitten/XSSor"
        return

    #
    # implement ITab
    #

    def getTabCaption(self):
        return "XSSor"

    def getUiComponent(self):
        return self._splitpane

    #
    # implement IHttpListener
    #

    def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
        if self.intercept == 1:
            if toolFlag == 4:
                # only process requests
                if not messageIsRequest:
                    self.checkForKey(messageInfo)

        return

    def printLog(self, message):
        self.consoleLog.setText(self.consoleLog.getText() + '\r\n' + message)

    def checkXSS(self, messageInfo, urlStr, requestBody, currentPayload):
        self.printLog('trying exploit with the payload: ' + currentPayload)
        requestURL = URL(urlStr.replace(self.xssKey, currentPayload))
        requestBody = requestBody.replace(self.xssKey,
                                          urllib.pathname2url(currentPayload))
        httpService = self._helpers.buildHttpService(
            str(requestURL.getHost()), int(requestURL.getPort()),
            requestURL.getProtocol() == "https")
        response = self._callbacks.makeHttpRequest(httpService, requestBody)
        responseInfo = self._helpers.analyzeResponse(response.getResponse())
        analyzedResponse = self._helpers.bytesToString(response.getResponse(
        ))  # change body offeset + make ui for affeccted pages
        responseBody = analyzedResponse.encode('utf-8')
        vulnOrNot = 'no'

        if currentPayload in responseBody:
            self.printLog('payload: ' + currentPayload +
                          ' found to be vulnarble')
            vulnOrNot = 'yes'
            # mark the payload
        if not len(self.affectedResponses) == 0:
            for request in self.affectedResponses:  # bug in case of no response in messageinfo
                self.printLog('checking affeccted page' +
                              str(request.getUrl()))
                requestURL = request.getUrl()
                httpService = self._helpers.buildHttpService(
                    str(requestURL.getHost()), int(requestURL.getPort()),
                    requestURL.getProtocol() == "https")
                affectedPageResponse = self._callbacks.makeHttpRequest(
                    httpService, request.getRequest())
                analyzedResponse = self._helpers.bytesToString(
                    affectedPageResponse.getResponse())
                responseBody = analyzedResponse.encode('utf-8')

            if currentPayload in responseBody:
                vulnOrNot = 'yes, affected page'
                self.printLog('affeccted page has been found as vulnerable')

        self._lock.acquire()
        row = self._log.size()
        self._log.add(
            LogEntry(
                self._helpers.analyzeRequest(response).getUrl(),
                self._callbacks.saveBuffersToTempFiles(response),
                currentPayload, vulnOrNot))
        self.fireTableRowsInserted(row, row)
        self._lock.release()

    def checkForKey(self, messageInfo):

        currentPayload = self.tagPayloads[0]
        requestInfo = self._helpers.analyzeRequest(messageInfo)
        requestHeaders = list(requestInfo.getHeaders())

        requestURL = requestInfo.getUrl()
        urlStr = str(requestURL)
        self.printLog('checking for xss key in URL: ' + urlStr)
        requestBody = self._helpers.bytesToString(messageInfo.getRequest())
        requestBody = re.sub(
            'Referer:.*\n', '', requestBody, flags=re.MULTILINE,
            count=1)  # workaround avoid xsskey in the referer newHeaders
        if self.xssKey in urlStr or self.xssKey in requestBody:
            self.printLog('xss key has been found')
            if self.bruteForceMode.isSelected():
                for i in range(0, self.payloadsModel.getSize()):
                    payload = self.payloadsModel.getElementAt(i)
                    self.checkXSS(messageInfo, urlStr, requestBody, payload)
            else:
                self.checkXSS(messageInfo, urlStr, requestBody,
                              self.basicPayloadTxt.getText())

                #

    # extend AbstractTableModel
    #

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

    def getColumnCount(self):
        return 3

    def getColumnName(self, columnIndex):
        if columnIndex == 0:
            return "URL"
        if columnIndex == 1:
            return "Payload"
        if columnIndex == 2:
            return "Vulnerable?"

        return ""

    def getValueAt(self, rowIndex, columnIndex):
        logEntry = self._log.get(rowIndex)
        if columnIndex == 0:
            # return self._callbacks.getToolName(logEntry._tool)
            return logEntry._url.toString()

        if columnIndex == 1:
            return logEntry._payload

        if columnIndex == 2:
            return logEntry._vulnOrNot

        return ""

    #
    # implement IMessageEditorController
    # this allows our request/response viewers to obtain details about the messages being displayed
    #

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

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

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

    def startOrStop(self, event):
        if self.startButton.getText() == "XSSor is off":
            self.startButton.setText("XSSor is on")
            self.startButton.setBackground(Color.GREEN)
            self.printLog('on, waiting for key word to be found (' +
                          self.xssKey + ')')
            self.intercept = 1
        else:
            self.startButton.setText("XSSor is off")
            self.startButton.setBackground(Color(255, 100, 91, 255))
            self.intercept = 0

    def clearAPList(self, event):
        self.affectedModel.clear()
        self.affectedResponses = ArrayList()

    #
    # implement IContextMenuFactory
    #
    def createMenuItems(self, invocation):
        responses = invocation.getSelectedMessages()
        if responses > 0:
            ret = LinkedList()
            affectedMenuItem = JMenuItem("XSSor: Add affected page")
            affectedMenuItem.addActionListener(
                handleMenuItems(self, responses[0], "affected"))
            ret.add(affectedMenuItem)
            return (ret)
        return null

    def addAfectedPage(self, messageInfo):
        self.affectedModel.addElement(
            str(self._helpers.analyzeRequest(messageInfo).getUrl()))
        self.affectedResponses.add(messageInfo)
Esempio n. 28
0
class BeautifierPanel(JPanel):
    def __init__(self):
        super(BeautifierPanel, self).__init__()
        self.setLayout(BorderLayout())

        self.beautifyTextArea = JTextArea(5, 10)
        self.beautifyTextArea.setLineWrap(True)
        self.beautifyTextArea.setDocument(self.CustomUndoPlainDocument())
        # The undo doesn't work well before replace text. Below is rough fix, so not need to know how undo work for now
        self.beautifyTextArea.setText(" ")
        self.beautifyTextArea.setText("")

        self.undoManager = UndoManager()
        self.beautifyTextArea.getDocument().addUndoableEditListener(
            self.undoManager)
        self.beautifyTextArea.getDocument().addDocumentListener(
            self.BeautifyDocumentListener(self))

        beautifyTextWrapper = JPanel(BorderLayout())
        beautifyScrollPane = JScrollPane(self.beautifyTextArea)
        beautifyTextWrapper.add(beautifyScrollPane, BorderLayout.CENTER)
        self.add(beautifyTextWrapper, BorderLayout.CENTER)

        self.beautifyButton = JButton("Beautify")
        self.beautifyButton.addActionListener(self.beautifyListener)
        self.undoButton = JButton("Undo")
        self.undoButton.addActionListener(self.undoListener)

        formatLabel = JLabel("Format:")
        self.formatsComboBox = JComboBox()
        for f in supportedFormats:
            self.formatsComboBox.addItem(f)

        self.statusLabel = JLabel("Status: Ready")
        preferredDimension = self.statusLabel.getPreferredSize()
        self.statusLabel.setPreferredSize(
            Dimension(preferredDimension.width + 20,
                      preferredDimension.height))
        self.sizeLabel = JLabel("0 B")
        preferredDimension = self.sizeLabel.getPreferredSize()
        self.sizeLabel.setPreferredSize(
            Dimension(preferredDimension.width + 64,
                      preferredDimension.height))
        self.sizeLabel.setHorizontalAlignment(SwingConstants.RIGHT)

        buttonsPanel = JPanel(FlowLayout())
        buttonsPanel.add(formatLabel)
        buttonsPanel.add(self.formatsComboBox)
        buttonsPanel.add(Box.createHorizontalStrut(10))
        buttonsPanel.add(self.beautifyButton)
        buttonsPanel.add(self.undoButton)

        bottomPanel = JPanel(BorderLayout())
        bottomPanel.add(self.statusLabel, BorderLayout.WEST)
        bottomPanel.add(buttonsPanel, BorderLayout.CENTER)
        bottomPanel.add(self.sizeLabel, BorderLayout.EAST)
        self.add(bottomPanel, BorderLayout.SOUTH)

        self.currentBeautifyThread = None

    class CustomUndoPlainDocument(PlainDocument):
        # Code from: https://stackoverflow.com/questions/24433089/jtextarea-settext-undomanager
        compoundEdit = CompoundEdit()

        def fireUndoableEditUpdate(self, e):
            if self.compoundEdit == None:
                super(BeautifierPanel.CustomUndoPlainDocument,
                      self).fireUndoableEditUpdate(e)
            else:
                self.compoundEdit.addEdit(e.getEdit())

        def replace(self, offset, length, text, attrs):
            if length == 0:
                super(BeautifierPanel.CustomUndoPlainDocument,
                      self).replace(offset, length, text, attrs)
            else:
                self.compoundEdit = CompoundEdit()
                super(BeautifierPanel.CustomUndoPlainDocument,
                      self).fireUndoableEditUpdate(
                          UndoableEditEvent(self, self.compoundEdit))
                super(BeautifierPanel.CustomUndoPlainDocument,
                      self).replace(offset, length, text, attrs)
                self.compoundEdit.end()
                self.compoundEdit = None

    def setText(self, text):
        self.beautifyTextArea.setText(text)

    def setRunningState(self):
        self.beautifyButton.setText("Cancel")
        self.undoButton.setEnabled(False)
        self.statusLabel.setText("Status: Running")

    def setReadyState(self):
        self.beautifyButton.setText("Beautify")
        self.undoButton.setEnabled(True)
        self.statusLabel.setText("Status: Ready")

    class BeautifyDocumentListener(DocumentListener):
        def __init__(self, beautifierPanel):
            super(BeautifierPanel.BeautifyDocumentListener, self).__init__()
            self.beautifierPanel = beautifierPanel

        def removeUpdate(self, e):
            self.updateSizeLabel()

        def insertUpdate(self, e):
            self.updateSizeLabel()

        def changedUpdate(self, e):
            pass

        def updateSizeLabel(self):
            length = len(self.beautifierPanel.beautifyTextArea.getText())
            if length >= 1024:
                length = "%.2f KB" % (length / 1024.0)
            else:
                length = "%d B" % length
            self.beautifierPanel.sizeLabel.setText(length)

    def beautifyListener(self, e):
        selectedFormat = self.formatsComboBox.getSelectedItem()
        data = self.beautifyTextArea.getText(
        )  # variable "data" is "unicode" type

        if self.currentBeautifyThread and self.currentBeautifyThread.isAlive():
            # TODO Need a graceful way to shutdown running beautify thread.
            self.currentBeautifyThread.callback = None
            self.currentBeautifyThread = None
            self.setReadyState()
        else:
            self.currentBeautifyThread = None
            self.setRunningState()

            def beautifyCallback(result):
                self.beautifyTextArea.setText(result)
                self.setReadyState()

            self.currentBeautifyThread = BeautifyThread(
                data, selectedFormat, beautifyCallback)
            self.currentBeautifyThread.start()

    def undoListener(self, e):
        if self.undoManager.canUndo():
            self.undoManager.undo()
Esempio n. 29
0
class Interfaz(JFrame):
    def __init__(self):
        super(Interfaz, self).__init__()
        self.filename = ''
        self.initUI()

    def initUI(self):

        self.panel = JPanel()
        self.panel.setLayout(GridLayout(6, 3))
        self.panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10))

        labelVacio1 = JLabel(' ')
        labelVacio2 = JLabel(' ')
        labelVacio3 = JLabel(' ')
        labelVacio4 = JLabel(' ')
        labelVacio5 = JLabel(' ')
        labelVacio6 = JLabel(' ')
        labelVacio7 = JLabel(' ')
        labelVacio8 = JLabel(' ')
        labelVacio9 = JLabel(' ')
        labelVacio10 = JLabel(' ')
        labelVacio11 = JLabel(' ')
        labelVacio12 = JLabel(' ')
        labelVacio13 = JLabel(' ')
        labelVacio14 = JLabel(' ')
        labelVacio15 = JLabel(' ')
        labelVacio16 = JLabel(' ')

        labelURL = JLabel(' Introduzca las URL que desee analizar:')
        chkboxSync = JCheckBox('Sincronizacion de cookies')
        self.textfieldURL = JTextField(15)
        chkboxResp = JCheckBox('Restauracion de cookies')
        labelFichero = JLabel(' O seleccione un fichero que las contenga:')

        self.area = JTextArea()
        pane = JScrollPane()
        pane.getViewport().add(self.area)

        panelFichero = JPanel()
        panelFichero.setLayout(None)
        buttonFichero = JButton("Seleccionar fichero",
                                actionPerformed=self.open)
        buttonFichero.setBounds(10, 0, 200, 25)
        panelFichero.add(buttonFichero)
        buttonEjecutar = JButton("Ejecutar", actionPerformed=self.ejecutar)

        buttonEjecutar.setFont(Font("Tahoma", Font.BOLD, 24))

        self.panel.add(labelURL)
        self.panel.add(labelVacio4)
        self.panel.add(chkboxSync)

        self.panel.add(self.textfieldURL)
        self.panel.add(labelVacio6)
        self.panel.add(chkboxResp)

        self.panel.add(labelFichero)
        self.panel.add(labelVacio9)
        self.panel.add(labelVacio10)

        self.panel.add(pane)
        self.panel.add(panelFichero)
        #self.panel.add(buttonFichero)
        self.panel.add(labelVacio11)

        self.panel.add(labelVacio12)
        self.panel.add(labelVacio13)
        self.panel.add(labelVacio14)

        self.panel.add(labelVacio15)
        self.panel.add(buttonEjecutar)
        self.panel.add(labelVacio16)

        self.add(self.panel)

        self.setTitle(
            "HERRAMIENTA PARA LA DETECCION DE TECNICAS DE SEGUIMIENTO DE USUARIOS EN LA WEB"
        )
        self.setSize(1000, 450)
        self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
        self.setLocationRelativeTo(None)
        self.setVisible(True)

    def open(self, e):
        filechooser = JFileChooser()
        filter = FileNameExtensionFilter("c files", ["c"])
        filechooser.addChoosableFileFilter(filter)
        ret = filechooser.showDialog(self.panel, "Elegir fichero")
        if ret == JFileChooser.APPROVE_OPTION:
            file = filechooser.getSelectedFile()
            text = self.readFile(file)
            self.area.setText(text)

    def readFile(self, file):
        filename = file.getCanonicalPath()
        self.filename = filename
        f = open(filename, "r")
        text = f.read()
        return text

    def ejecutar(self, e):
        JOptionPane.showMessageDialog(self.panel,
                                      "Ejecutando...\n Espere unos minutos.",
                                      "Info", JOptionPane.INFORMATION_MESSAGE)
        print("Ejecutando...")
        url = self.textfieldURL.getText()
        fichero = self.area.getText()
        urls_finales = ''

        if url == '' and fichero == '':
            self.error()
            return
        elif url != '' and fichero != '':
            print("Hay url y fichero")
            urls_finales = url + "\n" + fichero
            #self.writeFile(urls,1)

        elif fichero != '':
            print("Hay fichero")
            urls_finales = fichero
            #self.writeFile(fichero,1)

        elif url != '':
            print("Hay url")
            self.filename = "url"
            urls_finales = url
            #self.writeFile(url,1)

        else:
            print("Ha habido un error")

        self.writeFile(urls_finales, 1)
        f = open("bbdd.txt", "w")
        f.write(self.filename + "1\n")
        f.close()
        subprocess.call("python demo.py", shell=True)
        self.writeFile(urls_finales, 2)
        f = open("bbdd.txt", "a")
        f.write(self.filename + "2")
        f.close()
        subprocess.call("python demo.py", shell=True)
        subprocess.call("python rastreo_analisis.py", shell=True)

        self.initResultados()

    def initResultados(self):
        diag = JFrame()
        self.lineas = list()
        self.areaResultados = JTextArea()
        numLineas = self.readResultados()

        panelResultados = JPanel()
        #panelResultados.setAutoscrolls(True)
        panelResultados.setBorder(BorderFactory.createEtchedBorder())
        panelResultados.setLayout(GridLayout(0, 1))

        pane = JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                           JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)
        pane.viewport.view = self.areaResultados

        #pane.getViewport().add(panelResultados)

        diag.setTitle("RESULTADOS OBTENIDOS")

        diag.setSize(1000, 450)
        diag.setLayout(BorderLayout())
        diag.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
        diag.setLocationRelativeTo(None)
        diag.setVisible(True)

        panelResultados.add(pane)
        diag.add(panelResultados, BorderLayout.CENTER)

    def readResultados(self):
        count = 0
        f = open("resultados.txt", "r")
        resultados = f.read()
        self.areaResultados.setText(resultados)

        for linea in f:
            self.lineas.append(linea)
            count += 1

        return count

    def writeFile(self, urls, crawl):
        self.filename = self.filename.replace(".txt", '')
        f = open("URLs.txt", "w")
        f.write(self.filename + str(crawl) + ".txt" + '\n')
        f.write(urls)
        f.close()

    def error(self):
        JOptionPane.showMessageDialog(self.panel,
                                      "Debes introducir una URL o un fichero",
                                      "Error", JOptionPane.ERROR_MESSAGE)
class BurpExtender(IBurpExtender, ITab, IContextMenuFactory):

    #
    # implement IBurpExtender
    #

    def registerExtenderCallbacks(self, callbacks):

        # properties
        self._title = "Generate Python Template"
        self._templatePath = '###### ----> PUT HERE THE ABSOLUTE PATH TO template.py <--- ####'

        # set our extension name
        callbacks.setExtensionName(self._title)

        # keep a reference to our callbacks object
        self._callbacks = callbacks

        # obtain an extension helpers object
        self._helpers = callbacks.getHelpers()

        # obtain std streams
        self._stdout = PrintWriter(callbacks.getStdout(), True)
        self._stderr = PrintWriter(callbacks.getStderr(), True)

        # main pane (top/bottom)
        self._mainpane = JPanel()
        self._mainpane.setLayout(GridLayout(2, 1))

        # configure bottom pane for buttons
        self._botPane = JPanel()
        flowLayout = FlowLayout()
        self._botPane.setLayout(flowLayout)
        self._botPane.add(
            JButton("Generate", actionPerformed=self.regeneratePy))
        self._botPane.add(JButton("Export", actionPerformed=self.exportPy))

        # Configure pyViewer (JTextArea) for python output --> top pane
        self._pyViewer = JTextArea(5, 20)
        scrollPane = JScrollPane(self._pyViewer)
        self._pyViewer.setEditable(True)
        self._pyViewer.setText("Waiting request ...")

        ### Assign top / bottom components
        self._mainpane.add(scrollPane)
        self._mainpane.add(self._botPane)

        # customize our UI components
        callbacks.customizeUiComponent(self._mainpane)

        # add the custom tab to Burp's UI
        callbacks.addSuiteTab(self)

        # register ourselves as a ContextMenuFactory
        callbacks.registerContextMenuFactory(self)

        return

    def regeneratePy(self, event):
        pass

    def exportPy(self, event):
        chooseFile = JFileChooser()
        ret = chooseFile.showDialog(self._mainpane, "Choose file")
        filename = chooseFile.getSelectedFile().getCanonicalPath()
        self._stdout.println("Export to : " + filename)
        open(filename, 'w', 0).write(self._pyViewer.getText())

    #
    # implement ITab
    #

    def getTabCaption(self):
        return "PyTemplate"

    def getUiComponent(self):
        return self._mainpane

    #
    # implement IContextMenuFactory
    #

    def createMenuItems(self, invocation):
        # add a new item executing our action
        item = JMenuItem(
            self._title,
            actionPerformed=lambda x, inv=invocation: self.loadRequest(inv))
        return [item]

    def loadRequest(self, invocation):
        pyCode = self.pythonHeader()
        selectedMessages = invocation.getSelectedMessages()
        self._numbMessages = len(selectedMessages)
        self._currentMessageNumber = 1
        for message in selectedMessages:
            self._currentlyDisplayedItem = message
            pyCode += self.generateRequest()
            self._currentMessageNumber += 1
        pyCode += '\n' + self.generateMain()
        self._pyViewer.setText(pyCode)

    def pythonHeader(self):
        pyCode = "# -*- coding: utf-8 -*-\n\n"
        pyCode += "import requests\n"
        pyCode += "import time\n\n"
        return pyCode

    def formatHeaders(self, httpReqInfos):
        headers = httpReqInfos.getHeaders()[
            1:]  #First header is method+path : GET/POST ..
        formatHeaders = ""

        name, content = headers[0].split(':', 1)
        formatHeaders += 'headers["' + self.sanitizeStr(
            name) + '"] = ' + '"' + self.sanitizeStr(content) + '"\n'

        for header in headers[1:]:
            name, content = header.split(':', 1)
            if "Content-Length" not in name:
                if "Cookie" in name and self._numbMessages > 1 and self._currentMessageNumber != 1:
                    continue
                else:
                    formatHeaders += '    headers["' + self.sanitizeStr(
                        name) + '"] = ' + '"' + self.sanitizeStr(
                            content) + '"\n'
        return formatHeaders

    def sanitizeStr(self, strToValid):
        valid = str(strToValid)
        valid = valid.replace('"', '\\"')
        return valid.strip()

    def generateRequest(self):
        httpInfos = self._currentlyDisplayedItem.getHttpService()
        httpReq = self._currentlyDisplayedItem.getRequest()
        requestInfos = self._helpers.analyzeRequest(httpInfos, httpReq)
        pyTemplate = open(self._templatePath, 'r').read()
        pyCode = pyTemplate.replace('$$NUM$$', str(self._currentMessageNumber))
        pyCode = pyCode.replace('$$URL$$',
                                self.sanitizeStr(requestInfos.getUrl()))
        pyCode = pyCode.replace('$$HEADERS$$',
                                self.formatHeaders(requestInfos))
        pyCode = pyCode.replace('$$METHOD$$', requestInfos.getMethod())
        if requestInfos.getMethod() == "GET":
            trigger = "req = session.get(url, headers=headers, verify=False, allow_redirects=True)"
            pyCode = pyCode.replace('$$TRIGGER$$', trigger)
            pyCode = pyCode.replace('$$POST_DATA$$', '')
        if requestInfos.getMethod() == "POST":
            trigger = "req = session.post(url, headers=headers, data=post_data, verify=False, allow_redirects=True)"
            pyCode = pyCode.replace('$$TRIGGER$$', trigger)
            rawData = httpReq[requestInfos.getBodyOffset():].tostring()
            dataPyCode = '## POST DATA\n'
            dataPyCode += '    post_data = "' + self.sanitizeStr(
                rawData) + '"\n'
            pyCode = pyCode.replace('$$POST_DATA$$', dataPyCode)
        return pyCode + '\n'

    def generateMain(self):
        pyCode = 'if __name__ == "__main__":\n'
        pyCode += '    session = requests.Session()\n'
        for i in xrange(1, self._numbMessages + 1):
            pyCode += '    code_' + str(i) + ', time_' + str(
                i) + ', response_' + str(i) + ' = performRequest_' + str(
                    i) + '(session)\n'
        return pyCode