Esempio n. 1
0
class PropertyEditor(WindowAdapter):
    """
    Edits Tabular Properties of a given WindowAdapter
    """
    instances = {}
    last_location = None
    locations = {}
    last_size = None
    sizes = {}

    NEW_WINDOW_OFFSET = 32
    offset = NEW_WINDOW_OFFSET

    @staticmethod
    def get_instance(text="Property Editor",
                     columns=None,
                     data=None,
                     empty=None,
                     add_actions=True,
                     actions=None):
        """
        Singleton Method based on the text property. It tries to generate only one property configuration page per text.

        :param text: getinstance key
        :param columns: proparty columns it should be an array alike
        :param data: it contains the current property rows
        :param empty: empty row property when adding a new one
        :param add_actions: include or not new actions
        :param actions: default set of actions to be appended to Add and Delete Rows
        :return: a new instance of PropertyEditor or a reused one.
        """
        if not actions: actions = []
        if not columns: columns = []
        if data == None: data = []
        if not empty: empty = []
        try:
            PropertyEditor.instances[text]
        except KeyError:
            PropertyEditor.instances[text] = \
                PropertyEditor().__private_init__(text, columns, data, empty, add_actions, actions)
            try:
                PropertyEditor.instances[text].this.setLocation(
                    PropertyEditor.locations[text])
            except KeyError:
                if PropertyEditor.last_location:
                    PropertyEditor.instances[text].this.setLocation(
                        PropertyEditor.last_location.x + PropertyEditor.offset,
                        PropertyEditor.last_location.y + PropertyEditor.offset)
                    PropertyEditor.offset = PropertyEditor.NEW_WINDOW_OFFSET
            try:
                PropertyEditor.instances[text].this.setSize(
                    PropertyEditor.sizes[text])
            except KeyError:
                if PropertyEditor.last_size:
                    PropertyEditor.instances[text].this.setSize(
                        PropertyEditor.last_size)
            PropertyEditor.last_location = PropertyEditor.instances[
                text].this.getLocation()
            PropertyEditor.last_size = PropertyEditor.instances[
                text].this.getSize()
        ## Hack ON: Bring on Front
        PropertyEditor.instances[text].this.setAlwaysOnTop(True)
        PropertyEditor.instances[text].this.setAlwaysOnTop(False)
        ## Hack OFF
        return PropertyEditor.instances[text]

    def __private_init__(self,
                         text="Property Editor",
                         columns=None,
                         data=None,
                         empty=None,
                         add_actions=True,
                         actions=None):
        if not actions: actions = []
        if not columns: columns = []
        if data == None: data = []
        if not empty: empty = []

        self._text = text
        self.this = JFrame(text)
        self._table = JTable()
        self._dtm = DefaultTableModel(0, 0)
        self._dtm.setColumnIdentifiers(columns)
        self._table.setModel(self._dtm)
        self._data = data
        for d in data:
            self._dtm.addRow(d)
        self._pane = JScrollPane(self._table)
        self.this.add(self._pane)
        self._empty = empty

        self.this.addWindowListener(self)

        self._dtm.addTableModelListener(lambda _: self._update_model())
        self.this.setLocation(PropertyEditor.NEW_WINDOW_OFFSET,
                              PropertyEditor.NEW_WINDOW_OFFSET)

        if add_actions:
            self._popup = JPopupMenu()
            self._pane.setComponentPopupMenu(self._popup)
            inherits_popup_menu(self._pane)

            self._actions = actions
            self._actions.append(
                ExecutorAction('Remove Selected Rows',
                               action=lambda e: self._remove_row()))
            self._actions.append(
                ExecutorAction('Add New Row',
                               action=lambda e: self._add_row()))

            for action in self._actions:
                self._popup.add(action.menuitem)

        self.this.setForeground(Color.black)
        self.this.setBackground(Color.lightGray)
        self.this.pack()
        self.this.setVisible(True)
        self.this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE)

        return self

    def _add_row(self):
        """
        Add a new row the selection

        :return: None
        """
        self._dtm.addRow(self._empty)

    def _remove_row(self):
        """
        Remove all the selected rows from the selection
        :return:
        """
        rows = self._table.getSelectedRows()
        for i in range(0, len(rows)):
            self._dtm.removeRow(rows[i] - i)

    def windowClosing(self, evt):
        """
        Overrides WindowAdapter method

        :param evt: unused
        :return: None
        """
        PropertyEditor.locations[self._text] = self.this.getLocation()
        PropertyEditor.sizes[self._text] = self.this.getSize()
        PropertyEditor.last_location = self.this.getLocation()
        PropertyEditor.last_size = self.this.getSize()
        PropertyEditor.offset = 0
        self.this.setVisible(False)
        self.this.dispose()
        del PropertyEditor.instances[self._text]

    def _update_model(self):
        """
        Update the data content with the updated rows

        :return: None
        """
        del self._data[:]
        nRow = self._dtm.getRowCount()
        nCol = self._dtm.getColumnCount()
        for i in range(0, nRow):
            self._data.append([None] * nCol)
            for j in range(0, nCol):
                d = str(self._dtm.getValueAt(i, j)).lower()
                if d == 'none' or d == '':
                    self._data[i][j] = None
                elif d == 'true' or d == 't':
                    self._data[i][j] = True
                elif d == 'false' or d == 'f':
                    self._data[i][j] = False
                else:
                    try:
                        self._data[i][j] = int(self._dtm.getValueAt(i, j))
                    except ValueError:
                        self._data[i][j] = self._dtm.getValueAt(i, j)
Esempio n. 2
0
class BurpExtender(IBurpExtender, ITab, IHttpListener,
                   IMessageEditorController, AbstractTableModel,
                   IContextMenuFactory, IScannerCheck):
    name = "Femida XSS"
    conf_path = "./config.py"
    _jTabbedPane = JTabbedPane()
    _jPanel = JPanel()
    _jAboutPanel = JPanel()
    _jPanelConstraints = GridBagConstraints()
    _jLabelParameters = None
    _jTextFieldParameters = None
    _jLabelTechniques = None
    _jTextFieldURL = None
    _jLabelFuzzFactor = None
    _jTextFieldFuzzFactor = None
    _jLabelAdditionalCmdLine = None
    _jTextFieldAdditionalCmdLine = None
    _jButtonSetCommandLine = None
    _jLabelAbout = None
    _overwriteHeader = False
    _overwriteParam = False
    _forkRequestParam = False

    def doActiveScan(self, baseRequestResponse, insertionPoint):
        scan_issues = []
        try:
            requestString = str(baseRequestResponse.getRequest().tostring())
            newRequestString = self.prepareRequest(requestString)

            vulnerable, verifyingRequestResponse = self.quickCheckScan(
                newRequestString, baseRequestResponse)

        except Exception as msg:
            print(msg)

        return []

    def quickCheckScan(self, preparedRequest, requestResponse):
        check = self._callbacks.makeHttpRequest(
            requestResponse.getHttpService(),
            self._helpers.stringToBytes(preparedRequest))
        vulner = self._helpers.analyzeResponse(
            check.getResponse()).getStatusCode() == 200
        return vulner, check

    #
    # implement IBurpExtender
    #
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        self._callbacks.setExtensionName(self.name)
        self._callbacks.registerScannerCheck(self)

        self._dictPayloads = {}
        self._dictHeaders = {}
        self._dictParams = {}
        self.status_flag = False

        self.jfc = JFileChooser("./")
        self.jfc.setDialogTitle("Upload Payloads")
        self.jfc.setFileFilter(FileNameExtensionFilter("TXT file", ["txt"]))

        self._layout = GridBagLayout()
        self._jPanel.setLayout(self._layout)

        self._jLabelTechniques = JLabel("Press to start:")
        self.createAnyView(self._jLabelTechniques, 0, 0, 3, 1,
                           Insets(0, 0, 10, 0))

        self.submitSearchButton = swing.JButton(
            'Run proxy', actionPerformed=self.active_flag)
        self.submitSearchButton.setBackground(Color.WHITE)
        self.createAnyView(self.submitSearchButton, 3, 0, 6, 1,
                           Insets(0, 0, 10, 0))

        self._jPanel.setBounds(0, 0, 1000, 1000)
        self._jLabelTechniques = JLabel("Your URL (my.burpcollaborator.net):")
        self.createAnyView(self._jLabelTechniques, 0, 1, 3, 1,
                           Insets(0, 0, 10, 0))

        self._jTextFieldURL = JTextField("", 30)
        self._jTextFieldURL.addActionListener(self.setCallbackUrl)
        self.createAnyView(self._jTextFieldURL, 3, 1, 5, 1,
                           Insets(0, 0, 10, 0))

        self._forkRequestButton = swing.JButton(
            'Parallel Request', actionPerformed=self.forkRequest)
        self._forkRequestButton.setBackground(Color.WHITE)
        self.createAnyView(self._forkRequestButton, 8, 1, 1, 1,
                           Insets(0, 0, 10, 0))

        self._tableModelPayloads = DefaultTableModel()
        self._tableModelPayloads.addColumn("Payload")
        self._tableModelPayloads.addColumn("Active")

        self._tableModelHeaders = DefaultTableModel()
        self._tableModelHeaders.addColumn("Header")
        self._tableModelHeaders.addColumn("Active")

        self._tableModelParams = DefaultTableModel()
        self._tableModelParams.addColumn("Parameter")
        self._tableModelParams.addColumn("Active")

        self._payloadTable = self.createAnyTable(self._tableModelPayloads, 1,
                                                 Dimension(300, 200))
        self.createAnyView(self._payloadTable, 0, 2, 3, 1, Insets(0, 0, 0, 10))

        self._headerTable = self.createAnyTable(self._tableModelHeaders, 2,
                                                Dimension(300, 200))
        self.createAnyView(self._headerTable, 3, 2, 3, 1, Insets(0, 0, 0, 10))

        self._paramTable = self.createAnyTable(self._tableModelParams, 3,
                                               Dimension(300, 200))
        self.createAnyView(self._paramTable, 6, 2, 3, 1, Insets(0, 0, 0, 0))

        deletePayloadButton = swing.JButton(
            'Delete', actionPerformed=self.deleteToPayload)
        deletePayloadButton.setBackground(Color.WHITE)
        self.createAnyView(deletePayloadButton, 0, 3, 1, 1, Insets(3, 0, 0, 0))

        deletePayloadButton = swing.JButton(
            'Upload', actionPerformed=self.uploadToPayload)
        deletePayloadButton.setBackground(Color.WHITE)
        self.createAnyView(deletePayloadButton, 1, 3, 1, 1, Insets(3, 0, 0, 0))

        addPayloadButton = swing.JButton('Add',
                                         actionPerformed=self.addToPayload)
        addPayloadButton.setBackground(Color.WHITE)
        self.createAnyView(addPayloadButton, 2, 3, 1, 1, Insets(3, 0, 0, 10))

        deleteHeaderButton = swing.JButton('Delete',
                                           actionPerformed=self.deleteToHeader)
        deleteHeaderButton.setBackground(Color.WHITE)
        self.createAnyView(deleteHeaderButton, 3, 3, 1, 1, Insets(3, 0, 0, 0))

        self._overwriteHeaderButton = swing.JButton(
            'Overwrite', actionPerformed=self.overwriteHeader)
        self._overwriteHeaderButton.setBackground(Color.WHITE)
        self.createAnyView(self._overwriteHeaderButton, 4, 3, 1, 1,
                           Insets(3, 0, 0, 0))

        addHeaderButton = swing.JButton('Add',
                                        actionPerformed=self.addToHeader)
        addHeaderButton.setBackground(Color.WHITE)
        self.createAnyView(addHeaderButton, 5, 3, 1, 1, Insets(3, 0, 0, 10))

        deleteParamsButton = swing.JButton('Delete',
                                           actionPerformed=self.deleteToParams)
        deleteParamsButton.setBackground(Color.WHITE)
        self.createAnyView(deleteParamsButton, 6, 3, 1, 1, Insets(3, 0, 0, 0))

        self._overwriteParamButton = swing.JButton(
            'Overwrite', actionPerformed=self.overwriteParam)
        self._overwriteParamButton.setBackground(Color.WHITE)
        self.createAnyView(self._overwriteParamButton, 7, 3, 1, 1,
                           Insets(3, 0, 0, 0))

        addParamsButton = swing.JButton('Add',
                                        actionPerformed=self.addToParams)
        addParamsButton.setBackground(Color.WHITE)
        self.createAnyView(addParamsButton, 8, 3, 1, 1, Insets(3, 0, 0, 0))

        self._resultsTextArea = swing.JTextArea()
        resultsOutput = swing.JScrollPane(self._resultsTextArea)
        resultsOutput.setMinimumSize(Dimension(800, 200))
        self.createAnyView(resultsOutput, 0, 4, 9, 1, Insets(10, 0, 0, 0))

        self.clearSearchButton = swing.JButton(
            'Clear Search Output', actionPerformed=self.clearOutput)
        self.createAnyView(self.clearSearchButton, 3, 6, 3, 1,
                           Insets(3, 0, 0, 0))

        self._callbacks.customizeUiComponent(self._jPanel)
        self._callbacks.addSuiteTab(self)
        self.starterPack()

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

        return

    def createAnyTable(self, table_model, table_number, min_size):
        _table = JTable(table_model)
        _table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS)
        for i in range(2):
            column = _table.getColumnModel().getColumn(i)
            if i == 0:
                column.setPreferredWidth(250)
            else:
                column.setPreferredWidth(50)

        _scrolltable = JScrollPane(_table)
        _scrolltable.setMinimumSize(min_size)
        return _scrolltable

    def insertAnyTable(self, table, data):
        def detectTable(table):
            name = table.getColumnName(0)
            if name == 'Payloads':
                return 0
            elif name == 'Headers':
                return 1
            elif name == 'Parameters':
                return 2

        tableNum = detectTable(table)
        new_data = [str(x) for x in data]
        table.insertRow(table.getRowCount(), new_data)
        return table.getRowCount()

    def replaceLine(self, file_path, new_line):
        from tempfile import mkstemp
        from shutil import move
        from os import fdopen, remove
        #Create temp file
        fh, abs_path = mkstemp()
        with fdopen(fh, 'w') as new_file:
            with open(file_path) as old_file:
                for line in old_file:
                    a = re.findall('^Callback_url[ =]+(.+)$', line)
                    if a:
                        for k in a:
                            temp = k.replace("\'", "").replace("\"", "")
                            new_file.write(line.replace(temp, new_line))
                    else:
                        new_file.write(line)
        #Remove original file
        remove(file_path)
        #Move new file
        move(abs_path, file_path)

    def createAnyView(self, _component, gridx, gridy, gridwidth, gridheight,
                      insets):
        self._jPanelConstraints.fill = GridBagConstraints.HORIZONTAL
        self._jPanelConstraints.gridx = gridx
        self._jPanelConstraints.gridy = gridy
        self._jPanelConstraints.gridwidth = gridwidth
        self._jPanelConstraints.gridheight = gridheight
        self._jPanelConstraints.insets = insets
        self._jPanel.add(_component, self._jPanelConstraints)

    def createMenuItems(self, contextMenuInvocation):
        context = contextMenuInvocation.getInvocationContext()
        filterMenu = JMenu("Femida XSS")
        self._contextMenuData = contextMenuInvocation
        if (context == 0 or context == 1 or context == 2 or context == 3
                or context == 8 or context == 9):
            filterMenu.add(
                JMenuItem("Add to Headers",
                          actionPerformed=self.addToHeadersItem))
            filterMenu.add(
                JMenuItem("Add to Parameters",
                          actionPerformed=self.addToParametersItem))
            return Arrays.asList(filterMenu)
        return Arrays.asList([])

    def addToHeadersItem(self, event):
        start, end = self._contextMenuData.getSelectionBounds()
        message = self._contextMenuData.getSelectedMessages()[0]
        ctx = self._contextMenuData.getInvocationContext()

        if ctx == 0 or ctx == 2:
            message = message.getRequest()
        elif ctx == 1 or ctx == 3:
            message = message.getResponse()
        else:
            print(ctx)
            return
        try:
            selected_text = self._helpers.bytesToString(message)[start:end]
            self.insertAnyTable(self._tableModelHeaders,
                                [str(selected_text), '1'])
        except Exception:
            pass

    def addToParametersItem(self, event):
        start, end = self._contextMenuData.getSelectionBounds()
        message = self._contextMenuData.getSelectedMessages()[0]
        ctx = self._contextMenuData.getInvocationContext()

        if ctx == 0 or ctx == 2:
            message = message.getRequest()
        elif ctx == 1 or ctx == 3:
            message = message.getResponse()
        else:
            print(ctx)
            return
        try:
            selected_text = self._helpers.bytesToString(message)[start:end]
            self.insertAnyTable(self._tableModelParams,
                                [str(selected_text), '1'])
        except Exception:
            pass

    def starterPack(self):
        self.addFromFileAsync(config.Payloads, self._tableModelPayloads)
        self.addFromFileAsync(config.Headers, self._tableModelHeaders)
        self.addFromFileAsync(config.Parameters, self._tableModelParams)
        self._jTextFieldURL.setText(config.Callback_url)
        self._tableModelPayloads.addTableModelListener(
            MyTableModelListener(self._tableModelPayloads, self,
                                 self._dictPayloads, config.Payloads))
        self._tableModelHeaders.addTableModelListener(
            MyTableModelListener(self._tableModelHeaders, self,
                                 self._dictHeaders, config.Headers))
        self._tableModelParams.addTableModelListener(
            MyTableModelListener(self._tableModelParams, self,
                                 self._dictParams, config.Parameters))

    def setCallbackUrl(self, event):
        self.replaceLine(self.conf_path, self._jTextFieldURL.getText())
        self.appendToResults('New url={} saved.'.format(
            self._jTextFieldURL.getText()))

    def addToPayload(self, button):
        self.insertAnyTable(self._tableModelPayloads, ['', '1'])

    def addToHeader(self, button):
        self.insertAnyTable(self._tableModelHeaders, ['', '1'])

    def addToParams(self, button):
        self.insertAnyTable(self._tableModelParams, ['', '1'])

    def uploadToPayload(self, button):
        self._returnFileChooser = self.jfc.showDialog(None, "Open")
        if (self._returnFileChooser == JFileChooser.APPROVE_OPTION):
            selectedFile = self.jfc.getSelectedFile()
            self.fileUpload(selectedFile, self._tableModelPayloads)

    def deleteToPayload(self, button):
        try:
            val = self._tableModelPayloads.getValueAt(
                self._tableModelPayloads.getRowCount() - 1, 0)
            self._tableModelPayloads.removeRow(
                self._tableModelPayloads.getRowCount() - 1)
            self._dictPayloads.pop(val)
            self.saveToFileAsync(config.Payloads, self._dictPayloads)
        except Exception as msg:
            # print(msg)
            pass

    def deleteToHeader(self, button):
        try:
            val = self._tableModelHeaders.getValueAt(
                self._tableModelHeaders.getRowCount() - 1, 0)
            self._tableModelHeaders.removeRow(
                self._tableModelHeaders.getRowCount() - 1)
            self._dictHeaders.pop(val)
            self.saveToFileAsync(config.Headers, self._dictHeaders)
        except Exception as msg:
            # print(msg)
            pass

    def deleteToParams(self, button):
        try:
            val = self._tableModelParams.getValueAt(
                self._tableModelParams.getRowCount() - 1, 0)
            self._tableModelParams.removeRow(
                self._tableModelParams.getRowCount() - 1)
            self._dictParams.pop(val)
            self.saveToFileAsync(config.Parameters, self._dictParams)
        except Exception as msg:
            # print(msg)
            pass

    def clearOutput(self, button):
        self._resultsTextArea.setText("")

    def fileUpload(self, path, table):
        with open(str(path), "r") as f:
            for line in f:
                self.insertAnyTable(table, [str(line), '1'])

    def active_flag(self, button):
        if not self.status_flag:
            self.status_flag = True
            self.submitSearchButton.setBackground(Color.GRAY)
            self.appendToResults("Proxy start...\n")
        else:
            self.status_flag = False
            self.submitSearchButton.setBackground(Color.WHITE)
            self.appendToResults("Proxy stop...\n")

    def overwriteHeader(self, button):
        if not self._overwriteHeader:
            self._overwriteHeader = True
            self._overwriteHeaderButton.setBackground(Color.GRAY)
        else:
            self._overwriteHeader = False
            self._overwriteHeaderButton.setBackground(Color.WHITE)

    def overwriteParam(self, button):
        if not self._overwriteParam:
            self._overwriteParam = True
            self._overwriteParamButton.setBackground(Color.GRAY)
        else:
            self._overwriteParam = False
            self._overwriteParamButton.setBackground(Color.WHITE)

    def forkRequest(self, button):
        if not self._forkRequestParam:
            self._forkRequestParam = True
            self._forkRequestButton.setBackground(Color.GRAY)
        else:
            self._forkRequestParam = False
            self._forkRequestButton.setBackground(Color.WHITE)

    def prepareRequest(self, requestString, messageInfo=None):
        requestString = str(requestString)
        listHeader = re.findall('([\w-]+):\s?(.*)', requestString)
        dictRealHeaders = {x[0].lower(): x[1] for x in listHeader}

        selectedPayloads = {}
        for ind, k in enumerate(self._dictPayloads):
            if self._dictPayloads[k] == '1':
                selectedPayloads[k] = '1'
            else:
                continue

        for index, key in enumerate(self._dictHeaders):
            if key.lower() in dictRealHeaders.keys(
            ) and self._dictHeaders[key] == '1':
                if len(self._dictPayloads.keys()) == 0:
                    pass
                elif self._overwriteHeader:
                    payload = random.choice(selectedPayloads.keys())
                    payload = payload.replace(r"{URL}",
                                              self._jTextFieldURL.getText(), 1)
                    requestString = requestString.replace(
                        dictRealHeaders.get(key.lower()), payload, 1)
                elif not self._overwriteHeader:
                    payload = random.choice(selectedPayloads.keys())
                    payload = payload.replace(r"{URL}",
                                              self._jTextFieldURL.getText(), 1)
                    payload = dictRealHeaders.get(key.lower()) + payload
                    requestString = requestString.replace(
                        dictRealHeaders.get(key.lower()), payload, 1)
            else:
                pass

        for index, key in enumerate(self._dictParams):
            analyzed = self._helpers.analyzeRequest(requestString.encode())
            param = analyzed.getParameters()
            dictRealParams = {
                x.getName().lower():
                [x.getValue(),
                 x.getValueStart(),
                 x.getValueEnd()]
                for x in param
            }
            if key.lower() in dictRealParams.keys(
            ) and self._dictParams[key] == '1':
                if len(self._dictPayloads.keys()) == 0:
                    pass
                elif self._overwriteParam:
                    payload = random.choice(selectedPayloads.keys())
                    payload = payload.replace(r"{URL}",
                                              self._jTextFieldURL.getText(), 1)
                    start_word = dictRealParams[key.lower()][1]
                    end_word = dictRealParams[key.lower()][2]
                    requestString = requestString[:
                                                  start_word] + payload + requestString[
                                                      end_word:]

                elif not self._overwriteParam:
                    payload = random.choice(selectedPayloads.keys())
                    payload = payload.replace(r"{URL}",
                                              self._jTextFieldURL.getText(), 1)
                    payload = dictRealParams[key.lower()][0] + payload
                    start_word = dictRealParams[key.lower()][1]
                    end_word = dictRealParams[key.lower()][2]
                    requestString = requestString[:
                                                  start_word] + payload + requestString[
                                                      end_word:]
            else:
                pass
        return requestString

    def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
        if not self.status_flag:
            return
        # only process requests
        if not messageIsRequest:
            return

        if self._forkRequestParam:
            requestString = messageInfo.getRequest().tostring()
            # SOOOO HARD FIX! It should be better
            if requestString[0] == '@':
                messageInfo.setRequest(
                    self._helpers.stringToBytes(requestString[1:]))
            else:
                newRequestString = self.prepareRequest(requestString,
                                                       messageInfo)
                self.appendToResults('Parallel Request:')
                self.appendToResults(newRequestString.encode())
                newRequestString = '@' + newRequestString
                func = self._callbacks.makeHttpRequest
                thread = Thread(
                    target=func,
                    args=(messageInfo.getHttpService(),
                          self._helpers.stringToBytes(newRequestString)))
                thread.start()
        else:
            requestString = messageInfo.getRequest().tostring()
            newRequestString = self.prepareRequest(requestString, messageInfo)
            self.appendToResults(newRequestString.encode())
            messageInfo.setRequest(
                self._helpers.stringToBytes(newRequestString))

    # Fnction to provide output to GUI
    def appendToResults(self, s):
        def appendToResults_run(s):
            self._resultsTextArea.append(s)
            self._resultsTextArea.append('\n')

        swing.SwingUtilities.invokeLater(
            PyRunnable(appendToResults_run, str(s)))

    def addFromFileAsync(self, file, table):
        def addFromFile_run(file, table):
            if os.path.exists(file):
                with open(file, 'r') as f:
                    for row in f.readlines():
                        if row != '':
                            temp = row[:-1] if row[-1] == '\n' else row
                            self.insertAnyTable(table, [str(temp), '1'])

        swing.SwingUtilities.invokeLater(
            PyRunnable(addFromFile_run, file, table))

    def saveToFileAsync(self, file, data, isAppend=False):
        def saveToFile_run(file, data, isAppend):
            isAppend = 'w'
            with open(file, isAppend) as f:
                for i, k in enumerate(data):
                    f.write("{}\n".format(k))
                f.seek(-1, os.SEEK_END)
                f.truncate()

        swing.SwingUtilities.invokeLater(
            PyRunnable(saveToFile_run, file, data, isAppend))

    def getTabCaption(self):
        return self.name

    def getUiComponent(self):
        return self._jPanel