Example #1
0
class BurpExtender(IBurpExtender, IRequestInfo, IContextMenuFactory):
    def registerExtenderCallbacks(self, callbacks):
        self._actionName = "Export Objects"
        self._helers = callbacks.getHelpers()
        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        callbacks.setExtensionName("Export Objects")
        callbacks.registerContextMenuFactory(self)

        # obtain our output and error streams
        self._stderr = PrintWriter(callbacks.getStderr(), True)
        self._stdout = PrintWriter(callbacks.getStdout(), True)

        # write a message to the Burp alerts tab
        callbacks.issueAlert("Installed Export Objects.")

    def createMenuItems(self, invocation):
        menu = JMenu(self._actionName)
        self._menu_item = JMenuItem(
            "Export",
            None,
            actionPerformed=lambda x, inv=invocation: self.Action(inv),
        )
        menu.add(self._menu_item)
        return [menu]

    def Action(self, invocation):
        try:
            http_traffic = invocation.getSelectedMessages()
            traffic_length = len(http_traffic)
            counter = 0
            self._output_dir = u"/tmp"

            # choose output directory
            filechooser = JFileChooser()
            filechooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)

            selected = filechooser.showSaveDialog(self._menu_item)
            if selected == JFileChooser.APPROVE_OPTION:
                f = filechooser.getSelectedFile()
                self._output_dir = f.getAbsolutePath()

            self._stdout.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")

            while len(http_traffic) > 0:
                counter += 1
                target_traffic = http_traffic.pop()
                analyzedRequest = self._helpers.analyzeRequest(target_traffic)
                analyzedResponse = self._helpers.analyzeResponse(
                    target_traffic.getResponse())

                status_code = analyzedResponse.getStatusCode()
                mime_type = analyzedResponse.getStatedMimeType()
                url = analyzedRequest.getUrl()
                body_offset = analyzedResponse.getBodyOffset()

                # Skip empty response.
                if len(target_traffic.getResponse()[body_offset:]) <= 0:
                    self._stdout.printf("[%d/%d]\n", counter, traffic_length)
                    self._stdout.println("[-] %s's response is empty.", url)
                    continue

                # resolve filename from url.
                file_name = self.extract_filename(url)

                # check extention.
                if not self.has_extention(file_name):
                    ex = self.guess_extention(mime_type,
                                              target_traffic.getResponse())
                    file_name = file_name + "." + ex

                file_path = self._output_dir + u"/" + file_name.encode('utf-8')
                self._stdout.printf("[%d/%d]\n", counter, traffic_length)
                self._stdout.printf("url: %s\n", url)
                self._stdout.printf("status_code: %d\n", status_code)
                self._stdout.printf("mime_type: %s\n", mime_type)
                self._stdout.printf("body_offset: %d\n", body_offset)

                # extract object
                self.extract_obj(file_path, target_traffic.getResponse(),
                                 body_offset)

            self._stdout.printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n")

        except Exception as e:
            self._stderr.println("[!] In Action.")
            self._stderr.println(e)

    def extract_filename(self, url):
        uri = url.toURI()
        path = uri.getPath().encode('utf-8')
        file_name = path.split(u"/")[-1]
        return file_name

    def has_extention(self, file_name):
        return len(file_name.split(".")) > 1

    def guess_extention(self, mime, res):
        if mime == u"JPEG":
            return u"jpg"
        elif mime == u"GIF":
            return u"gif"
        elif mime == u"PNG":
            return u"png"
        elif mime == u"HTML":
            return u"html"
        elif mime == u"JSON":
            return u"json"
        elif mime == u"XML":
            return u"xml"
        elif mime == u"scrip":
            # Only javascript is supported.
            return u"js"
        elif mime == u"text":
            return u"txt"
        elif mime == u"image":
            return u"ico"
        else:
            return u""

    def extract_obj(self, file_path, res, offset):
        try:
            f = File(file_path)

            # check same name file.
            counter = 0
            while True:

                # The same file name is not exists.
                if not f.exists():
                    break

                # Count up the file name.
                counter += 1
                stem = u"".join(file_path.split(u".")[:-1])
                ex = file_path.split(u".")[-1]

                _file_path = u"{}({}).{}".format(stem, counter, ex)
                f = File(_file_path)

            fos = FileOutputStream(f)

            fos.write(res[offset:])
            self._stdout.printf("save as \"%s\".\n\n", f.getPath())

            fos.close()

        except Exception as e:
            self._stderr.println("[!] In extract_obj.")
            self._stderr.println(e)