Beispiel #1
0
def get_traffic_details(scan_id, traffic_id):
    """
    The HTTP request and response associated with a vulnerability, usually the
    user will first get /scans/1/kb/3 and from there (if needed) browse to
    this resource where the HTTP traffic is available

    :param scan_id: The scan ID
    :param traffic_id: The ID of the request/response
    :return: HTTP request and response in base64 format
    """
    scan_info = get_scan_info_from_id(scan_id)
    if scan_info is None:
        abort(404, 'Scan not found')

    history_db = HistoryItem()

    try:
        details = history_db.read(traffic_id)
    except DBException:
        msg = 'Failed to retrieve request with id %s from DB.'
        abort(404, msg)
        return

    data = {
        'request': b64encode(details.request.dump()),
        'response': b64encode(details.response.dump())
    }

    return jsonify(data)
Beispiel #2
0
def get_traffic_details(scan_id, traffic_id):
    """
    The HTTP request and response associated with a vulnerability, usually the
    user will first get /scans/1/kb/3 and from there (if needed) browse to
    this resource where the HTTP traffic is available

    :param scan_id: The scan ID
    :param traffic_id: The ID of the request/response
    :return: HTTP request and response in base64 format
    """
    scan_info = get_scan_info_from_id(scan_id)
    if scan_info is None:
        abort(404, 'Scan not found')

    history_db = HistoryItem()

    try:
        details = history_db.read(traffic_id)
    except DBException:
        msg = 'Failed to retrieve request with id %s from DB.'
        abort(404, msg)
        return

    data = {'request': b64encode(details.request.dump()),
            'response': b64encode(details.response.dump())}

    return jsonify(data)
Beispiel #3
0
def response_dump(_id):
    """
    :param _id: The ID to query in the database
    :return: The response as unicode
    """
    _history = HistoryItem()

    try:
        details = _history.read(_id)
    except DBException:
        return None

    return smart_unicode(details.response.dump().strip())
Beispiel #4
0
def response_dump(_id):
    """
    :param _id: The ID to query in the database
    :return: The response as unicode
    """
    _history = HistoryItem()

    try:
        details = _history.read(_id)
    except DBException:
        return None

    return smart_unicode(details.response.dump().strip())
Beispiel #5
0
class FuzzyRequests(entries.RememberingWindow):
    """Infrastructure to generate fuzzy HTTP requests.

    :author: Facundo Batista <facundobatista =at= taniquetil.com.ar>
    """
    def __init__(self, w3af, initial_request=None):
        super(FuzzyRequests,
              self).__init__(w3af, "fuzzyreq", "w3af - Fuzzy Requests",
                             "Fuzzy_Requests")
        self.w3af = w3af
        self.historyItem = HistoryItem()
        mainhbox = gtk.HBox()

        # To store the responses
        self.responses = []

        # ---- left pane ----
        vbox = gtk.VBox()
        mainhbox.pack_start(vbox, False, False)

        # we create the buttons first, to pass them
        analyzBut = gtk.Button("Analyze")
        self.sendPlayBut = entries.SemiStockButton(
            "", gtk.STOCK_MEDIA_PLAY, "Sends the pending requests")
        self.sendStopBut = entries.SemiStockButton(
            "", gtk.STOCK_MEDIA_STOP, "Stops the request being sent")
        self.sSB_state = helpers.PropagateBuffer(
            self.sendStopBut.set_sensitive)
        self.sSB_state.change(self, False)

        # Fix content length checkbox
        self._fix_content_lengthCB = gtk.CheckButton(
            'Fix content length header')
        self._fix_content_lengthCB.set_active(True)
        self._fix_content_lengthCB.show()

        # request
        self.originalReq = RequestPart(
            self,
            w3af, [
                analyzBut.set_sensitive, self.sendPlayBut.set_sensitive,
                functools.partial(self.sSB_state.change, 'rRV')
            ],
            editable=True,
            widgname='fuzzyrequest')

        if initial_request is None:
            self.originalReq.show_raw(FUZZY_REQUEST_EXAMPLE, '')
        else:
            (initialUp, initialDn) = initial_request
            self.originalReq.show_raw(initialUp, initialDn)

        # Add the right button popup menu to the text widgets
        rawTextView = self.originalReq.get_view_by_id('HttpRawView')
        rawTextView.textView.connect("populate-popup", self._populate_popup)

        # help
        helplabel = gtk.Label()
        helplabel.set_selectable(True)
        helplabel.set_markup(FUZZY_HELP)
        self.originalReq.append_page(helplabel, gtk.Label("Syntax help"))
        helplabel.show()
        self.originalReq.show()
        vbox.pack_start(self.originalReq, True, True, padding=5)
        vbox.show()

        # the commands
        t = gtk.Table(2, 4)
        analyzBut.connect("clicked", self._analyze)
        t.attach(analyzBut, 0, 2, 0, 1)
        self.analyzefb = gtk.Label("0 requests")
        self.analyzefb.set_sensitive(False)
        t.attach(self.analyzefb, 2, 3, 0, 1)
        self.preview = gtk.CheckButton("Preview")
        t.attach(self.preview, 3, 4, 0, 1)
        self.sPB_signal = self.sendPlayBut.connect("clicked", self._send_start)
        t.attach(self.sendPlayBut, 0, 1, 1, 2)
        self.sendStopBut.connect("clicked", self._send_stop)
        t.attach(self.sendStopBut, 1, 2, 1, 2)
        self.sendfb = gtk.Label("0 ok, 0 errors")
        self.sendfb.set_sensitive(False)
        t.attach(self.sendfb, 2, 3, 1, 2)
        t.attach(self._fix_content_lengthCB, 3, 4, 1, 2)
        t.show_all()

        vbox.pack_start(t, False, False, padding=5)

        # ---- throbber pane ----
        vbox = gtk.VBox()
        self.throbber = helpers.Throbber()
        self.throbber.set_sensitive(False)
        vbox.pack_start(self.throbber, False, False)
        vbox.show()
        mainhbox.pack_start(vbox, False, False)

        # ---- right pane ----
        vbox = gtk.VBox()
        mainhbox.pack_start(vbox)

        # A label to show the id of the response
        self.title0 = gtk.Label()
        self.title0.show()
        vbox.pack_start(self.title0, False, True)

        # result itself
        self.resultReqResp = ReqResViewer(w3af,
                                          withFuzzy=False,
                                          editableRequest=False,
                                          editableResponse=False)
        self.resultReqResp.set_sensitive(False)
        vbox.pack_start(self.resultReqResp, True, True, padding=5)
        vbox.show()

        # result control
        centerbox = gtk.HBox()
        self.pagesControl = entries.PagesControl(w3af, self.page_change)
        centerbox.pack_start(self.pagesControl, True, False)
        centerbox.show()

        # cluster responses button
        image = gtk.Image()
        image.set_from_file(
            os.path.join(ROOT_PATH, 'core', 'ui', 'gui', 'data',
                         'cluster_data.png'))
        image.show()
        self.clusterButton = gtk.Button(label='Cluster responses')
        self.clusterButton.connect("clicked", self._clusterData)
        self.clusterButton.set_sensitive(False)
        self.clusterButton.set_image(image)
        self.clusterButton.show()
        centerbox.pack_start(self.clusterButton, True, False)

        # clear responses button
        self.clearButton = entries.SemiStockButton(
            'Clear Responses',
            gtk.STOCK_CLEAR,
            tooltip='Clear all HTTP responses from fuzzer window')
        self.clearButton.connect("clicked", self._clearResponses)
        self.clearButton.set_sensitive(False)
        self.clearButton.show()
        centerbox.pack_start(self.clearButton, True, False)

        vbox.pack_start(centerbox, False, False, padding=5)

        # Show all!
        self._sendPaused = True
        self.vbox.pack_start(mainhbox)
        self.vbox.show()
        mainhbox.show()
        self.show()

    def _populate_popup(self, textview, menu):
        """Populates the menu with the fuzzing items."""
        menu.append(gtk.SeparatorMenuItem())
        main_generator_menu = gtk.MenuItem(_("Generators"))
        main_generator_menu.set_submenu(create_generator_menu(self))
        menu.append(main_generator_menu)
        menu.show_all()

    def _clearResponses(self, widg):
        """Clears all the responses from the fuzzy window."""
        self.responses = []
        self.resultReqResp.request.clear_panes()
        self.resultReqResp.response.clear_panes()
        self.resultReqResp.set_sensitive(False)
        self.clusterButton.set_sensitive(False)
        self.clearButton.set_sensitive(False)
        self.pagesControl.deactivate()

    def _clusterData(self, widg):
        """Analyze if we can cluster the responses and do it."""
        data = []
        for resp in self.responses:
            if resp[0]:
                reqid = resp[1]
                historyItem = self.historyItem.read(reqid)
                data.append(historyItem.response)

        if data:
            distance_function_selector(self.w3af, data)
        else:
            # Let the user know ahout the problem
            msg = "There are no HTTP responses available to cluster."
            dlg = gtk.MessageDialog(None, gtk.DIALOG_MODAL,
                                    gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, msg)
            opt = dlg.run()
            dlg.destroy()

    def _analyze(self, widg):
        """Handles the Analyze part."""
        (request, postbody) = self.originalReq.get_both_texts_raw()
        try:
            fg = helpers.coreWrap(fuzzygen.FuzzyGenerator, request, postbody)
        except fuzzygen.FuzzyError:
            return

        self.analyzefb.set_text("%d requests" % fg.calculate_quantity())
        self.analyzefb.set_sensitive(True)

        # raise the window only if preview is active
        if self.preview.get_active():
            PreviewWindow(self.w3af, self, fg)

    def _send_stop(self, widg=None):
        """Stop the requests being sent."""
        self._sendStopped = True
        self.sendPlayBut.change_internals("", gtk.STOCK_MEDIA_PLAY,
                                          "Sends the pending requests")
        self.sendPlayBut.disconnect(self.sPB_signal)
        self.sPB_signal = self.sendPlayBut.connect("clicked", self._send_start)
        self.sSB_state.change(self, False)
        self.throbber.running(False)

    def _send_pause(self, widg):
        """Pause the requests being sent."""
        self._sendPaused = True
        self.sendPlayBut.change_internals("", gtk.STOCK_MEDIA_PLAY,
                                          "Sends the pending requests")
        self.sendPlayBut.disconnect(self.sPB_signal)
        self.sPB_signal = self.sendPlayBut.connect("clicked", self._send_play)
        self.throbber.running(False)

    def _send_play(self, widg):
        """Continue sending the requests."""
        self._sendPaused = False
        self.sendPlayBut.change_internals('', gtk.STOCK_MEDIA_PAUSE,
                                          'Sends the pending requests')
        self.sendPlayBut.disconnect(self.sPB_signal)
        self.sPB_signal = self.sendPlayBut.connect('clicked', self._send_pause)
        self.throbber.running(True)

    def _send_start(self, widg):
        """Start sending the requests."""
        (request, postbody) = self.originalReq.get_both_texts_raw()

        try:
            fg = helpers.coreWrap(fuzzygen.FuzzyGenerator, request, postbody)
        except fuzzygen.FuzzyError:
            return

        quant = fg.calculate_quantity()
        if quant > 20:
            msg = "Are you sure you want to send %d requests?" % quant
            dlg = gtk.MessageDialog(None, gtk.DIALOG_MODAL,
                                    gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO,
                                    msg)
            opt = dlg.run()
            dlg.destroy()
            if opt != gtk.RESPONSE_YES:
                return

        # Get the fix content length value
        fixContentLength = self._fix_content_lengthCB.get_active()

        # initial state
        self.result_ok = 0
        self.result_err = 0
        self._sendPaused = False
        self._sendStopped = False
        requestGenerator = fg.generate()

        # change the buttons
        self.sendPlayBut.change_internals('', gtk.STOCK_MEDIA_PAUSE,
                                          'Pauses the requests sending')
        self.sendPlayBut.disconnect(self.sPB_signal)
        self.sPB_signal = self.sendPlayBut.connect('clicked', self._send_pause)
        self.sSB_state.change(self, True)
        self.throbber.running(True)

        # let's send the requests!
        gobject.timeout_add(100, self._real_send, fixContentLength,
                            requestGenerator)

    def _real_send(self, fixContentLength, requestGenerator):
        """This is the one that actually sends the requests, if corresponds.

        :param fixContentLength: if the length should be fixed by the core.
        :param requestGenerator: where to ask for the requests
        """
        if self._sendStopped:
            return False
        if self._sendPaused:
            return True

        try:
            realreq, realbody = requestGenerator.next()
        except StopIteration:
            # finished with all the requests!
            self._send_stop()
            return False

        # Clear any errors that might have been generated by previous runs
        # of this or other GUI tools
        self.w3af.uri_opener.clear()

        try:
            http_resp = self.w3af.uri_opener.send_raw_request(
                realreq, realbody, fixContentLength)
            error_msg = None
            self.result_ok += 1
        except HTTPRequestException, e:
            # One HTTP request failed
            error_msg = str(e)
            http_resp = None
            self.result_err += 1
        except ScanMustStopException, e:
            # Many HTTP requests failed and the URL library wants to stop
            error_msg = str(e)
            self.result_err += 1

            # Let the user know about the problem
            msg = "Stopped sending requests because of the following" \
                  " unexpected error:\n\n%s"

            helpers.FriendlyExceptionDlg(msg % error_msg)
            return False
Beispiel #6
0
class FuzzyRequests(entries.RememberingWindow):
    """Infrastructure to generate fuzzy HTTP requests.

    :author: Facundo Batista <facundobatista =at= taniquetil.com.ar>
    """
    def __init__(self, w3af, initial_request=None):
        super(FuzzyRequests, self).__init__(w3af, "fuzzyreq",
                                            "w3af - Fuzzy Requests",
                                            "Fuzzy_Requests")
        self.w3af = w3af
        self.historyItem = HistoryItem()
        mainhbox = gtk.HBox()

        # To store the responses
        self.responses = []

        # ---- left pane ----
        vbox = gtk.VBox()
        mainhbox.pack_start(vbox, False, False)

        # we create the buttons first, to pass them
        analyzBut = gtk.Button("Analyze")
        self.sendPlayBut = entries.SemiStockButton(
            "", gtk.STOCK_MEDIA_PLAY, "Sends the pending requests")
        self.sendStopBut = entries.SemiStockButton(
            "", gtk.STOCK_MEDIA_STOP, "Stops the request being sent")
        self.sSB_state = helpers.PropagateBuffer(
            self.sendStopBut.set_sensitive)
        self.sSB_state.change(self, False)

        # Fix content length checkbox
        self._fix_content_lengthCB = gtk.CheckButton('Fix content length header')
        self._fix_content_lengthCB.set_active(True)
        self._fix_content_lengthCB.show()

        # request
        self.originalReq = RequestPart(self, w3af,
                                       [analyzBut.set_sensitive,
                                        self.sendPlayBut.set_sensitive,
                                        functools.partial(self.sSB_state.change, "rRV")],
                                       editable=True,
                                       widgname="fuzzyrequest")

        if initial_request is None:
            self.originalReq.show_raw(FUZZY_REQUEST_EXAMPLE, '')
        else:
            (initialUp, initialDn) = initial_request
            self.originalReq.show_raw(initialUp, initialDn)

        # Add the right button popup menu to the text widgets
        rawTextView = self.originalReq.get_view_by_id('HttpRawView')
        rawTextView.textView.connect("populate-popup", self._populate_popup)

        # help
        helplabel = gtk.Label()
        helplabel.set_selectable(True)
        helplabel.set_markup(FUZZYHELP)
        self.originalReq.append_page(helplabel, gtk.Label("Syntax help"))
        helplabel.show()
        self.originalReq.show()
        vbox.pack_start(self.originalReq, True, True, padding=5)
        vbox.show()

        # the commands
        t = gtk.Table(2, 4)
        analyzBut.connect("clicked", self._analyze)
        t.attach(analyzBut, 0, 2, 0, 1)
        self.analyzefb = gtk.Label("0 requests")
        self.analyzefb.set_sensitive(False)
        t.attach(self.analyzefb, 2, 3, 0, 1)
        self.preview = gtk.CheckButton("Preview")
        t.attach(self.preview, 3, 4, 0, 1)
        self.sPB_signal = self.sendPlayBut.connect("clicked", self._send_start)
        t.attach(self.sendPlayBut, 0, 1, 1, 2)
        self.sendStopBut.connect("clicked", self._send_stop)
        t.attach(self.sendStopBut, 1, 2, 1, 2)
        self.sendfb = gtk.Label("0 ok, 0 errors")
        self.sendfb.set_sensitive(False)
        t.attach(self.sendfb, 2, 3, 1, 2)
        t.attach(self._fix_content_lengthCB, 3, 4, 1, 2)
        t.show_all()

        vbox.pack_start(t, False, False, padding=5)

        # ---- throbber pane ----
        vbox = gtk.VBox()
        self.throbber = helpers.Throbber()
        self.throbber.set_sensitive(False)
        vbox.pack_start(self.throbber, False, False)
        vbox.show()
        mainhbox.pack_start(vbox, False, False)

        # ---- right pane ----
        vbox = gtk.VBox()
        mainhbox.pack_start(vbox)

        # A label to show the id of the response
        self.title0 = gtk.Label()
        self.title0.show()
        vbox.pack_start(self.title0, False, True)

        # result itself
        self.resultReqResp = ReqResViewer(w3af, withFuzzy=False,
                                          editableRequest=False,
                                          editableResponse=False)
        self.resultReqResp.set_sensitive(False)
        vbox.pack_start(self.resultReqResp, True, True, padding=5)
        vbox.show()

        # result control
        centerbox = gtk.HBox()
        self.pagesControl = entries.PagesControl(w3af, self._pageChange)
        centerbox.pack_start(self.pagesControl, True, False)
        centerbox.show()

        # cluster responses button
        image = gtk.Image()
        image.set_from_file(os.path.join(ROOT_PATH, 'core', 'ui', 'gui',
                                         'data', 'cluster_data.png'))
        image.show()
        self.clusterButton = gtk.Button(label='Cluster responses')
        self.clusterButton.connect("clicked", self._clusterData)
        self.clusterButton.set_sensitive(False)
        self.clusterButton.set_image(image)
        self.clusterButton.show()
        centerbox.pack_start(self.clusterButton, True, False)

        # clear responses button
        self.clearButton = entries.SemiStockButton(
            'Clear Responses', gtk.STOCK_CLEAR,
            tooltip='Clear all HTTP responses from fuzzer window')
        self.clearButton.connect("clicked", self._clearResponses)
        self.clearButton.set_sensitive(False)
        self.clearButton.show()
        centerbox.pack_start(self.clearButton, True, False)

        vbox.pack_start(centerbox, False, False, padding=5)

        # Show all!
        self._sendPaused = True
        self.vbox.pack_start(mainhbox)
        self.vbox.show()
        mainhbox.show()
        self.show()

    def _populate_popup(self, textview, menu):
        """Populates the menu with the fuzzing items."""
        menu.append(gtk.SeparatorMenuItem())
        main_generator_menu = gtk.MenuItem(_("Generators"))
        main_generator_menu.set_submenu(create_generator_menu(self))
        menu.append(main_generator_menu)
        menu.show_all()

    def _clearResponses(self, widg):
        """Clears all the responses from the fuzzy window."""
        self.responses = []
        self.resultReqResp.request.clear_panes()
        self.resultReqResp.response.clear_panes()
        self.resultReqResp.set_sensitive(False)
        self.clusterButton.set_sensitive(False)
        self.clearButton.set_sensitive(False)
        self.pagesControl.deactivate()

    def _clusterData(self, widg):
        """Analyze if we can cluster the responses and do it."""
        data = []
        for resp in self.responses:
            if resp[0]:
                reqid = resp[1]
                historyItem = self.historyItem.read(reqid)
                data.append(historyItem.response)

        if data:
            distance_function_selector(self.w3af, data)
        else:
            # Let the user know ahout the problem
            msg = "There are no HTTP responses available to cluster."
            dlg = gtk.MessageDialog(None, gtk.DIALOG_MODAL,
                                    gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, msg)
            opt = dlg.run()
            dlg.destroy()

    def _analyze(self, widg):
        """Handles the Analyze part."""
        (request, postbody) = self.originalReq.get_both_texts_raw()
        try:
            fg = helpers.coreWrap(fuzzygen.FuzzyGenerator, request, postbody)
        except fuzzygen.FuzzyError:
            return

        self.analyzefb.set_text("%d requests" % fg.calculate_quantity())
        self.analyzefb.set_sensitive(True)

        # raise the window only if preview is active
        if self.preview.get_active():
            PreviewWindow(self.w3af, self, fg)

    def _send_stop(self, widg=None):
        """Stop the requests being sent."""
        self._sendStopped = True
        self.sendPlayBut.change_internals(
            "", gtk.STOCK_MEDIA_PLAY, "Sends the pending requests")
        self.sendPlayBut.disconnect(self.sPB_signal)
        self.sPB_signal = self.sendPlayBut.connect("clicked", self._send_start)
        self.sSB_state.change(self, False)
        self.throbber.running(False)

    def _send_pause(self, widg):
        """Pause the requests being sent."""
        self._sendPaused = True
        self.sendPlayBut.change_internals("", gtk.STOCK_MEDIA_PLAY,
                                          "Sends the pending requests")
        self.sendPlayBut.disconnect(self.sPB_signal)
        self.sPB_signal = self.sendPlayBut.connect("clicked", self._send_play)
        self.throbber.running(False)

    def _send_play(self, widg):
        """Continue sending the requests."""
        self._sendPaused = False
        self.sendPlayBut.change_internals("", gtk.STOCK_MEDIA_PAUSE,
                                          "Sends the pending requests")
        self.sendPlayBut.disconnect(self.sPB_signal)
        self.sPB_signal = self.sendPlayBut.connect("clicked", self._send_pause)
        self.throbber.running(True)

    def _send_start(self, widg):
        """Start sending the requests."""
        (request, postbody) = self.originalReq.get_both_texts_raw()
        
        try:
            fg = helpers.coreWrap(fuzzygen.FuzzyGenerator, request, postbody)
        except fuzzygen.FuzzyError:
            return

        quant = fg.calculate_quantity()
        if quant > 20:
            msg = "Are you sure you want to send %d requests?" % quant
            dlg = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING,
                                    gtk.BUTTONS_YES_NO, msg)
            opt = dlg.run()
            dlg.destroy()
            if opt != gtk.RESPONSE_YES:
                return

        # Get the fix content length value
        fixContentLength = self._fix_content_lengthCB.get_active()

        # initial state
        self.result_ok = 0
        self.result_err = 0
        self._sendPaused = False
        self._sendStopped = False
        requestGenerator = fg.generate()

        # change the buttons
        self.sendPlayBut.change_internals("", gtk.STOCK_MEDIA_PAUSE,
                                          "Pauses the requests sending")
        self.sendPlayBut.disconnect(self.sPB_signal)
        self.sPB_signal = self.sendPlayBut.connect("clicked", self._send_pause)
        self.sSB_state.change(self, True)
        self.throbber.running(True)

        # let's send the requests!
        gobject.timeout_add(100, self._real_send, fixContentLength,
                            requestGenerator)

    def _real_send(self, fixContentLength, requestGenerator):
        """This is the one that actually sends the requests, if corresponds.

        :param fixContentLength: if the lenght should be fixed by the core.
        :param requestGenerator: where to ask for the requests
        """
        if self._sendStopped:
            return False
        if self._sendPaused:
            return True

        try:
            realreq, realbody = requestGenerator.next()
        except StopIteration:
            # finished with all the requests!
            self._send_stop()
            return False

        try:
            http_resp = self.w3af.uri_opener.send_raw_request(realreq, realbody,
                                                              fixContentLength)
            error_msg = None
            self.result_ok += 1
        except HTTPRequestException, e:
            # One HTTP request failed
            error_msg = str(e)
            http_resp = None
            self.result_err += 1
        except ScanMustStopException, e:
            # Many HTTP requests failed and the URL library wants to stop
            error_msg = str(e)
            self.result_err += 1

            # Let the user know about the problem
            msg = "Stopped sending requests because of the following"\
                  " unexpected error:\n\n%s"

            helpers.FriendlyExceptionDlg(msg % error_msg)
            return False
Beispiel #7
0
class FullKBTree(KBTree):
    """A tree showing all the info.

    This also gives a long description of the element when clicked.

    :param kbbrowser: The KB Browser
    :param filter: The filter to show which elements

    :author: Facundo Batista <facundobatista =at= taniquetil.com.ar>
    """
    def __init__(self, w3af, kbbrowser, ifilter):
        super(FullKBTree, self).__init__(w3af, ifilter,
                                         'Knowledge Base', strict=False)
        self._historyItem = HistoryItem()
        self.kbbrowser = kbbrowser
        self.connect('cursor-changed', self._showDesc)
        self.show()

    def _showDesc(self, tv):
        """Shows the description at the right

        :param tv: the treeview.
        """
        (path, column) = tv.get_cursor()
        if path is None:
            return

        instance = self.get_instance(path)
        if not isinstance(instance, Info):
            return
        
        longdesc = instance.get_desc()
        self.kbbrowser.explanation.set_text(longdesc)

        if not instance.get_id():
            self.clear_request_response_viewer()
            return

        #
        # We have two different cases:
        #
        # 1) The object is related to ONLY ONE request / response
        # 2) The object is related to MORE THAN ONE request / response
        #
        # For 1), we show the classic view, and for 2) we show the classic
        # view with a "page control"
        #
        # Work:
        #
        if len(instance.get_id()) == 1:
            # There is ONLY ONE id related to the object
            # This is 1)
            self.kbbrowser.pagesControl.deactivate()
            self.kbbrowser._pageChange(0)
            self.kbbrowser.pagesControl.hide()
            self.kbbrowser.title0.hide()

            search_id = instance.get_id()[0]
            try:
                history_item = self._historyItem.read(search_id)
            except DBException:
                msg = _('The HTTP data with id %s is not inside the database.')
                self._show_message(_('Error'), msg % search_id)
                self.clear_request_response_viewer()
                return

            # Error handling for .trace file problems
            # https://github.com/andresriancho/w3af/issues/1174
            try:
                # These lines will trigger the code that reads the .trace file
                # from disk and if they aren't there an exception will rise
                history_item.request
                history_item.response
            except IOError, ioe:
                self._show_message(_('Error'), str(ioe))
                return

            # Now we know that these two lines will work and we won't trigger
            # https://github.com/andresriancho/w3af/issues/1174
            self.kbbrowser.rrV.request.show_object(history_item.request)
            self.kbbrowser.rrV.response.show_object(history_item.response)

            # Don't forget to highlight if necessary
            severity = instance.get_severity()
            for s in instance.get_to_highlight():
                self.kbbrowser.rrV.response.highlight(s, severity)

        else:
Beispiel #8
0
class KBBrowser(entries.RememberingHPaned):
    """Show the Knowledge Base, with the filter and the tree.

    :author: Facundo Batista <facundobatista =at= taniquetil.com.ar>
    """
    def __init__(self, w3af):
        super(KBBrowser, self).__init__(w3af, "pane-kbbrowser", 250)

        # Internal variables:
        #
        # Here I save the request and response ids to be used in the page control
        self.req_res_ids = []
        # This is to search the DB and print the different request and responses as they are
        # requested from the page control, "_pageChange" method.
        self._historyItem = HistoryItem()

        # the filter to the tree
        filterbox = gtk.HBox()
        self.filters = {}

        def make_but(label, signal, initial):
            but = gtk.CheckButton(label)
            but.set_active(initial)
            but.connect("clicked", self.type_filter, signal)
            self.filters[signal] = initial
            but.show()
            filterbox.pack_start(but, expand=False, fill=False, padding=2)
        make_but("Vulnerabilities", "vuln", True)
        make_but("Informations", "info", True)
        filterbox.show()

        # the kb tree
        self.kbtree = FullKBTree(w3af, self, self.filters)

        # all in the first pane
        scrollwin21 = gtk.ScrolledWindow()
        scrollwin21.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scrollwin21.add(self.kbtree)
        scrollwin21.show()

        # the filter and tree box
        treebox = gtk.VBox()
        treebox.pack_start(filterbox, expand=False, fill=False)
        treebox.pack_start(scrollwin21)
        treebox.show()

        # the explanation
        explan_tv = gtk.TextView()
        explan_tv.set_editable(False)
        explan_tv.set_cursor_visible(False)
        explan_tv.set_wrap_mode(gtk.WRAP_WORD)
        self.explanation = explan_tv.get_buffer()
        explan_tv.show()
        scrollwin22 = gtk.ScrolledWindow()
        scrollwin22.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scrollwin22.add_with_viewport(explan_tv)
        scrollwin22.show()

        # The request/response viewer
        self.rrV = reqResViewer.reqResViewer(w3af, withAudit=False)
        self.rrV.set_sensitive(False)

        # Create the title label to show the request id
        self.title0 = gtk.Label()
        self.title0.show()

        # Create page changer to handle info/vuln objects that have MORE THAN ONE
        # related request/response
        self.pagesControl = entries.PagesControl(w3af, self._pageChange, 0)
        self.pagesControl.deactivate()
        self._pageChange(0)
        centerbox = gtk.HBox()
        centerbox.pack_start(self.pagesControl, True, False)

        # Add everything to a vbox
        vbox_rrv_centerbox = gtk.VBox()
        vbox_rrv_centerbox.pack_start(self.title0, False, True)
        vbox_rrv_centerbox.pack_start(self.rrV, True, True)
        vbox_rrv_centerbox.pack_start(centerbox, False, False)

        # and show
        vbox_rrv_centerbox.show()
        self.pagesControl.show()
        centerbox.show()

        # And now put everything inside the vpaned
        vpanedExplainAndView = entries.RememberingVPaned(
            w3af, "pane-kbbexplainview", 100)
        vpanedExplainAndView.pack1(scrollwin22)
        vpanedExplainAndView.pack2(vbox_rrv_centerbox)
        vpanedExplainAndView.show()

        # pack & show
        self.pack1(treebox)
        self.pack2(vpanedExplainAndView)
        self.show()

    def type_filter(self, button, ptype):
        """Changes the filter of the KB in the tree."""
        self.filters[ptype] = button.get_active()
        self.kbtree.set_filter(self.filters)

    def _pageChange(self, page):
        """
        Handle the page change in the page control.
        """
        # Only do something if I have a list of request and responses
        if self.req_res_ids:
            request_id = self.req_res_ids[page]
            try:
                historyItem = self._historyItem.read(request_id)
            except:
                # the request brought problems
                self.rrV.request.clear_panes()
                self.rrV.response.clear_panes()
                self.rrV.set_sensitive(False)
                self.title0.set_markup("<b>Error</b>")
            else:
                self.title0.set_markup("<b>Id: %d</b>" % request_id)
                self.rrV.request.show_object(historyItem.request)
                self.rrV.response.show_object(historyItem.response)
                self.rrV.set_sensitive(True)
Beispiel #9
0
    def _write_findings_to_xml(self):
        """
        Write all the findings to the XML file
        :return: None, we write the data to the XML
        """
        # HistoryItem to get requests/responses
        req_history = HistoryItem()

        for i in kb.kb.get_all_findings():
            message_node = self._xml.createElement('vulnerability')

            message_node.setAttribute('severity', xml_str(i.get_severity()))
            message_node.setAttribute('method', xml_str(i.get_method()))
            message_node.setAttribute('url', xml_str(i.get_url()))
            message_node.setAttribute('var', xml_str(i.get_token_name()))
            message_node.setAttribute('name', xml_str(i.get_name()))
            message_node.setAttribute('plugin', xml_str(i.get_plugin_name()))

            # Wrap description in a <description> element and put it above the
            # request/response elements
            desc_str = xml_str(i.get_desc(with_id=False))
            description_node = self._xml.createElement('description')
            description = self._xml.createTextNode(desc_str)
            description_node.appendChild(description)
            message_node.appendChild(description_node)

            # If there is information from the vulndb, then we should write it
            if i.has_db_details():
                desc_str = xml_str(i.get_long_description())
                description_node = self._xml.createElement('long-description')
                description = self._xml.createTextNode(desc_str)
                description_node.appendChild(description)
                message_node.appendChild(description_node)

                fix_str = xml_str(i.get_fix_guidance())
                fix_node = self._xml.createElement('fix-guidance')
                fix = self._xml.createTextNode(fix_str)
                fix_node.appendChild(fix)
                message_node.appendChild(fix_node)

                fix_effort_str = xml_str(i.get_fix_effort())
                fix_node = self._xml.createElement('fix-effort')
                fix = self._xml.createTextNode(fix_effort_str)
                fix_node.appendChild(fix)
                message_node.appendChild(fix_node)

                if i.get_references():
                    references_node = self._xml.createElement('references')

                    for ref in i.get_references():
                        ref_node = self._xml.createElement('reference')
                        ref_node.setAttribute('title', xml_str(ref.title))
                        ref_node.setAttribute('url', xml_str(ref.url))
                        references_node.appendChild(ref_node)

                    message_node.appendChild(references_node)

            if i.get_id():
                message_node.setAttribute('id', str(i.get_id()))
                # Wrap all transactions in a http-transactions node
                transaction_set = self._xml.createElement('http-transactions')
                message_node.appendChild(transaction_set)

                for request_id in i.get_id():
                    try:
                        details = req_history.read(request_id)
                    except DBException:
                        msg = 'Failed to retrieve request with id %s from DB.'
                        print(msg % request_id)
                        continue

                    # Wrap the entire http transaction in a single block
                    action_set = self._xml.createElement('http-transaction')
                    action_set.setAttribute('id', str(request_id))
                    transaction_set.appendChild(action_set)

                    request_node = self._xml.createElement('http-request')
                    self.report_http_action(request_node, details.request)
                    action_set.appendChild(request_node)

                    response_node = self._xml.createElement('http-response')
                    self.report_http_action(response_node, details.response)
                    action_set.appendChild(response_node)

            self._top_elem.appendChild(message_node)
Beispiel #10
0
class FullKBTree(KBTree):
    def __init__(self, w3af, kbbrowser, ifilter):
        """A tree showing all the info.

        This also gives a long description of the element when clicked.

        :param kbbrowser: The KB Browser
        :param filter: The filter to show which elements

        :author: Facundo Batista <facundobatista =at= taniquetil.com.ar>
        """
        super(FullKBTree, self).__init__(w3af,
                                         ifilter,
                                         'Knowledge Base',
                                         strict=False)
        self._historyItem = HistoryItem()
        self.kbbrowser = kbbrowser
        self.connect('cursor-changed', self._showDesc)
        self.show()

    def _showDesc(self, tv):
        """Shows the description at the right

        :param tv: the treeview.
        """
        (path, column) = tv.get_cursor()
        if path is None:
            return

        instance = self.get_instance(path)
        if not isinstance(instance, Info):
            return

        longdesc = instance.get_desc()
        self.kbbrowser.explanation.set_text(longdesc)

        if not instance.get_id():
            self.clear_request_response_viewer()
            return

        #
        # We have two different cases:
        #
        # 1) The object is related to ONLY ONE request / response
        # 2) The object is related to MORE THAN ONE request / response
        #
        # For 1), we show the classic view, and for 2) we show the classic
        # view with a "page control"
        #
        # Work:
        #
        if len(instance.get_id()) == 1:
            # There is ONLY ONE id related to the object
            # This is 1)
            self.kbbrowser.pagesControl.deactivate()
            self.kbbrowser._pageChange(0)
            self.kbbrowser.pagesControl.hide()
            self.kbbrowser.title0.hide()

            search_id = instance.get_id()[0]
            try:
                history_item = self._historyItem.read(search_id)
            except DBException:
                msg = _('The HTTP data with id %s is not inside the database.')
                self._show_message(_('Error'), msg % search_id)
                self.clear_request_response_viewer()
                return

            # Error handling for .trace file problems
            # https://github.com/andresriancho/w3af/issues/1174
            try:
                # These lines will trigger the code that reads the .trace file
                # from disk and if they aren't there an exception will rise
                history_item.request
                history_item.response
            except IOError, ioe:
                self._show_message(_('Error'), str(ioe))
                return

            # Now we know that these two lines will work and we won't trigger
            # https://github.com/andresriancho/w3af/issues/1174
            self.kbbrowser.rrV.request.show_object(history_item.request)
            self.kbbrowser.rrV.response.show_object(history_item.response)

            # Don't forget to highlight if necessary
            severity = instance.get_severity()
            for s in instance.get_to_highlight():
                self.kbbrowser.rrV.response.highlight(s, severity)

        else:
Beispiel #11
0
class KBBrowser(entries.RememberingHPaned):
    """Show the Knowledge Base, with the filter and the tree.

    :author: Facundo Batista <facundobatista =at= taniquetil.com.ar>
    """
    def __init__(self, w3af):
        super(KBBrowser, self).__init__(w3af, "pane-kbbrowser", 250)

        # Internal variables:
        #
        # Here I save the request and response ids to be used in the page control
        self.req_res_ids = []
        # This is to search the DB and print the different request and responses as they are
        # requested from the page control, "_pageChange" method.
        self._historyItem = HistoryItem()

        # the filter to the tree
        filterbox = gtk.HBox()
        self.filters = {}

        def make_but(label, signal, initial):
            but = gtk.CheckButton(label)
            but.set_active(initial)
            but.connect("clicked", self.type_filter, signal)
            self.filters[signal] = initial
            but.show()
            filterbox.pack_start(but, expand=False, fill=False, padding=2)

        make_but("Vulnerabilities", "vuln", True)
        make_but("Informations", "info", True)
        filterbox.show()

        # the kb tree
        self.kbtree = FullKBTree(w3af, self, self.filters)

        # all in the first pane
        scrollwin21 = gtk.ScrolledWindow()
        scrollwin21.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scrollwin21.add(self.kbtree)
        scrollwin21.show()

        # the filter and tree box
        treebox = gtk.VBox()
        treebox.pack_start(filterbox, expand=False, fill=False)
        treebox.pack_start(scrollwin21)
        treebox.show()

        # the explanation
        explan_tv = gtk.TextView()
        explan_tv.set_editable(False)
        explan_tv.set_cursor_visible(False)
        explan_tv.set_wrap_mode(gtk.WRAP_WORD)
        self.explanation = explan_tv.get_buffer()
        explan_tv.show()
        scrollwin22 = gtk.ScrolledWindow()
        scrollwin22.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scrollwin22.add_with_viewport(explan_tv)
        scrollwin22.show()

        # The request/response viewer
        self.rrV = ReqResViewer(w3af, withAudit=False)
        self.rrV.set_sensitive(False)

        # Create the title label to show the request id
        self.title0 = gtk.Label()
        self.title0.show()

        # Create page changer to handle info/vuln objects that have MORE THAN ONE
        # related request/response
        self.pagesControl = entries.PagesControl(w3af, self._pageChange, 0)
        self.pagesControl.deactivate()
        self._pageChange(0)
        centerbox = gtk.HBox()
        centerbox.pack_start(self.pagesControl, True, False)

        # Add everything to a vbox
        vbox_rrv_centerbox = gtk.VBox()
        vbox_rrv_centerbox.pack_start(self.title0, False, True)
        vbox_rrv_centerbox.pack_start(self.rrV, True, True)
        vbox_rrv_centerbox.pack_start(centerbox, False, False)

        # and show
        vbox_rrv_centerbox.show()
        self.pagesControl.show()
        centerbox.show()

        # And now put everything inside the vpaned
        vpanedExplainAndView = entries.RememberingVPaned(
            w3af, "pane-kbbexplainview", 100)
        vpanedExplainAndView.pack1(scrollwin22)
        vpanedExplainAndView.pack2(vbox_rrv_centerbox)
        vpanedExplainAndView.show()

        # pack & show
        self.pack1(treebox)
        self.pack2(vpanedExplainAndView)
        self.show()

    def type_filter(self, button, ptype):
        """Changes the filter of the KB in the tree."""
        self.filters[ptype] = button.get_active()
        self.kbtree.set_filter(self.filters)

    def _pageChange(self, page):
        """
        Handle the page change in the page control.
        """
        # Only do something if I have a list of request and responses
        if self.req_res_ids:
            request_id = self.req_res_ids[page]
            try:
                historyItem = self._historyItem.read(request_id)
            except:
                # the request brought problems
                self.rrV.request.clear_panes()
                self.rrV.response.clear_panes()
                self.rrV.set_sensitive(False)
                self.title0.set_markup("<b>Error</b>")
            else:
                self.title0.set_markup("<b>Id: %d</b>" % request_id)
                self.rrV.request.show_object(historyItem.request)
                self.rrV.response.show_object(historyItem.response)
                self.rrV.set_sensitive(True)
Beispiel #12
0
class FullKBTree(KBTree):
    def __init__(self, w3af, kbbrowser, ifilter):
        """A tree showing all the info.

        This also gives a long description of the element when clicked.

        :param kbbrowser: The KB Browser
        :param ifilter: The filter to show which elements

        :author: Facundo Batista <facundobatista =at= taniquetil.com.ar>
        """
        super(FullKBTree, self).__init__(w3af,
                                         ifilter,
                                         'Knowledge Base',
                                         strict=False)
        self._historyItem = HistoryItem()
        self.kbbrowser = kbbrowser
        self.connect('cursor-changed', self._show_desc)
        self.show()

    def _create_reference_list(self, info):
        """
        :return: A list with references for this info instance in markdown
                 format so I can add them to the description.
        """
        if not info.get_references():
            return ''

        output = '\n\n### References\n'
        for ref in info.get_references():
            output += ' * [%s](%s)\n' % (ref.title, ref.url)

        return output

    def _show_desc(self, tv):
        """Shows the description in the right section

        :param tv: the treeview.
        """
        (path, column) = tv.get_cursor()
        if path is None:
            return

        instance = self.get_instance(path)
        if not isinstance(instance, Info):
            return

        summary = instance.get_desc()
        self.kbbrowser.explanation.set_text(summary)
        self.kbbrowser.vuln_notebook.set_current_page(0)

        if instance.has_db_details():
            desc_markdown = instance.get_long_description()
            desc_markdown += '\n\n### Fix guidance\n'
            desc_markdown += instance.get_fix_guidance()
            desc_markdown += self._create_reference_list(instance)
            desc = markdown(desc_markdown)

            self.kbbrowser.description.load_html_string(desc, FILE)
        else:
            self.kbbrowser.description.load_html_string(
                DB_VULN_NOT_FOUND, FILE)

        if not instance.get_id():
            self.clear_request_response_viewer()
            return

        #
        # We have two different cases:
        #
        # 1) The object is related to ONLY ONE request / response
        # 2) The object is related to MORE THAN ONE request / response
        #
        # For 1), we show the classic view, and for 2) we show the classic
        # view with a "page control"
        #
        # Work:
        #
        if len(instance.get_id()) == 1:
            # There is ONLY ONE id related to the object
            # This is 1)
            self.kbbrowser.pagesControl.deactivate()
            self.kbbrowser.page_change(0)
            self.kbbrowser.pagesControl.hide()
            self.kbbrowser.title0.hide()

            search_id = instance.get_id()[0]
            try:
                history_item = self._historyItem.read(search_id)
            except DBException:
                msg = _('The HTTP data with id %s is not inside the database.')
                self._show_message(_('Error'), msg % search_id)
                self.clear_request_response_viewer()
                return

            # Error handling for .trace file problems
            # https://github.com/andresriancho/w3af/issues/1174
            try:
                # These lines will trigger the code that reads the .trace file
                # from disk and if they aren't there an exception will rise
                history_item.request
                history_item.response
            except IOError, ioe:
                self._show_message(_('Error'), str(ioe))
                return

            # Now we know that these two lines will work and we won't trigger
            # https://github.com/andresriancho/w3af/issues/1174
            self.kbbrowser.rrV.request.show_object(history_item.request)
            self.kbbrowser.rrV.response.show_object(history_item.response)

            # Don't forget to highlight if necessary
            severity = instance.get_severity()
            for s in instance.get_to_highlight():
                self.kbbrowser.rrV.response.highlight(s, severity)

        else:
Beispiel #13
0
class KBBrowser(entries.RememberingHPaned):
    """Show the Knowledge Base, with the filter and the tree.

    :author: Facundo Batista <facundobatista =at= taniquetil.com.ar>
    """
    def __init__(self, w3af):
        super(KBBrowser, self).__init__(w3af, "pane-kbbrowser", 250)

        # Internal variables:
        # Save the request and response ids to be used in the page control
        self.req_res_ids = []
        # This is to search the DB and print the different request and responses
        # as they are requested from the page control, "page_change" method.
        self._historyItem = HistoryItem()

        # the filter to the tree
        filterbox = gtk.HBox()
        self.filters = {}

        def make_but(label, signal, initial):
            but = gtk.CheckButton(label)
            but.set_active(initial)
            but.connect('clicked', self.type_filter, signal)
            self.filters[signal] = initial
            but.show()
            filterbox.pack_start(but, expand=False, fill=False, padding=2)

        make_but('Vulnerability', 'vuln', True)
        make_but('Information', 'info', True)
        filterbox.show()

        # the kb tree
        self.kbtree = FullKBTree(w3af, self, self.filters)

        # all in the first pane
        kbtree_scrollwin = gtk.ScrolledWindow()
        kbtree_scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        kbtree_scrollwin.add(self.kbtree)
        kbtree_scrollwin.show()

        # the filter and tree box
        treebox = gtk.VBox()
        treebox.pack_start(filterbox, expand=False, fill=False)
        treebox.pack_start(kbtree_scrollwin)
        treebox.show()

        # the vulnerability information
        summary = self.get_notebook_summary(w3af)
        description = self.get_notebook_description()

        self.vuln_notebook = gtk.Notebook()
        self.vuln_notebook.append_page(summary, gtk.Label('Summary'))
        self.vuln_notebook.append_page(description, gtk.Label('Description'))
        self.vuln_notebook.set_current_page(0)
        self.vuln_notebook.show()

        # pack & show
        self.pack1(treebox)
        self.pack2(self.vuln_notebook)
        self.show()

    def get_notebook_description(self):
        # Make the HTML viewable area

        self.description = webkit.WebView()

        # Disable the plugins for the webview
        ws = self.description.get_settings()
        ws.set_property('enable-plugins', False)
        self.description.set_settings(ws)
        self.description.show()

        desc_scroll = gtk.ScrolledWindow()
        desc_scroll.add(self.description)
        desc_scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        desc_scroll.show()

        return desc_scroll

    def get_notebook_summary(self, w3af):
        summary_tv = gtk.TextView()
        summary_tv.set_editable(False)
        summary_tv.set_cursor_visible(False)
        summary_tv.set_wrap_mode(gtk.WRAP_WORD)
        self.explanation = summary_tv.get_buffer()
        summary_tv.show()

        summary_scrollwin = gtk.ScrolledWindow()
        summary_scrollwin.set_policy(gtk.POLICY_AUTOMATIC,
                                     gtk.POLICY_AUTOMATIC)
        summary_scrollwin.add_with_viewport(summary_tv)
        summary_scrollwin.show()

        # The request/response viewer
        self.rrV = ReqResViewer(w3af, withAudit=False)
        self.rrV.set_sensitive(False)

        # Create the title label to show the request id
        self.title0 = gtk.Label()
        self.title0.show()

        # Create page changer to handle info/vuln objects that have MORE THAN
        # ONE related request/response
        self.pagesControl = entries.PagesControl(w3af, self.page_change, 0)
        self.pagesControl.deactivate()
        self.page_change(0)
        center_box = gtk.HBox()
        center_box.pack_start(self.pagesControl, True, False)

        # Title, request/response and paginator all go together in a vbox
        http_data_vbox = gtk.VBox()
        http_data_vbox.pack_start(self.title0, False, True)
        http_data_vbox.pack_start(self.rrV, True, True)
        http_data_vbox.pack_start(center_box, False, False)

        # and show
        http_data_vbox.show()
        self.pagesControl.show()
        center_box.show()

        # The summary and http data go in a vbox too
        summary_data_vbox = entries.RememberingVPaned(w3af,
                                                      'pane-kbbexplainview',
                                                      100)
        summary_data_vbox.pack1(summary_scrollwin)
        summary_data_vbox.pack2(http_data_vbox)
        summary_data_vbox.show()

        return summary_data_vbox

    def type_filter(self, button, ptype):
        """Changes the filter of the KB in the tree."""
        self.filters[ptype] = button.get_active()
        self.kbtree.set_filter(self.filters)

    def page_change(self, page):
        """
        Handle the page change in the page control.
        """
        # Only do something if I have a list of request and responses
        if self.req_res_ids:
            request_id = self.req_res_ids[page]
            try:
                historyItem = self._historyItem.read(request_id)
            except:
                # the request brought problems
                self.rrV.request.clear_panes()
                self.rrV.response.clear_panes()
                self.rrV.set_sensitive(False)
                self.title0.set_markup("<b>Error</b>")
            else:
                self.title0.set_markup("<b>Id: %d</b>" % request_id)
                self.rrV.request.show_object(historyItem.request)
                self.rrV.response.show_object(historyItem.response)
                self.rrV.set_sensitive(True)
Beispiel #14
0
class FullKBTree(KBTree):
    def __init__(self, w3af, kbbrowser, ifilter):
        """A tree showing all the info.

        This also gives a long description of the element when clicked.

        :param kbbrowser: The KB Browser
        :param ifilter: The filter to show which elements

        :author: Facundo Batista <facundobatista =at= taniquetil.com.ar>
        """
        super(FullKBTree, self).__init__(w3af, ifilter,
                                         'Knowledge Base', strict=False)
        self._historyItem = HistoryItem()
        self.kbbrowser = kbbrowser
        self.connect('cursor-changed', self._show_desc)
        self.show()

    def _create_reference_list(self, info):
        """
        :return: A list with references for this info instance in markdown
                 format so I can add them to the description.
        """
        if not info.get_references():
            return ''

        output = '\n\n### References\n'
        for ref in info.get_references():
            output += ' * [%s](%s)\n' % (ref.title, ref.url)

        return output

    def _show_desc(self, tv):
        """Shows the description in the right section

        :param tv: the treeview.
        """
        (path, column) = tv.get_cursor()
        if path is None:
            return

        instance = self.get_instance(path)
        if not isinstance(instance, Info):
            return
        
        summary = instance.get_desc()
        self.kbbrowser.explanation.set_text(summary)
        self.kbbrowser.vuln_notebook.set_current_page(0)

        if instance.has_db_details():
            desc_markdown = instance.get_long_description()
            desc_markdown += '\n\n### Fix guidance\n'
            desc_markdown += instance.get_fix_guidance()
            desc_markdown += self._create_reference_list(instance)
            desc = markdown(desc_markdown)

            self.kbbrowser.description.load_html_string(desc, FILE)
        else:
            self.kbbrowser.description.load_html_string(DB_VULN_NOT_FOUND, FILE)

        if not instance.get_id():
            self.clear_request_response_viewer()
            return

        #
        # We have two different cases:
        #
        # 1) The object is related to ONLY ONE request / response
        # 2) The object is related to MORE THAN ONE request / response
        #
        # For 1), we show the classic view, and for 2) we show the classic
        # view with a "page control"
        #
        # Work:
        #
        if len(instance.get_id()) == 1:
            # There is ONLY ONE id related to the object
            # This is 1)
            self.kbbrowser.pagesControl.deactivate()
            self.kbbrowser.page_change(0)
            self.kbbrowser.pagesControl.hide()
            self.kbbrowser.title0.hide()

            search_id = instance.get_id()[0]
            try:
                history_item = self._historyItem.read(search_id)
            except DBException:
                msg = _('The HTTP data with id %s is not inside the database.')
                self._show_message(_('Error'), msg % search_id)
                self.clear_request_response_viewer()
                return

            # Error handling for .trace file problems
            # https://github.com/andresriancho/w3af/issues/1174
            try:
                # These lines will trigger the code that reads the .trace file
                # from disk and if they aren't there an exception will rise
                history_item.request
                history_item.response
            except IOError, ioe:
                self._show_message(_('Error'), str(ioe))
                return

            # Now we know that these two lines will work and we won't trigger
            # https://github.com/andresriancho/w3af/issues/1174
            self.kbbrowser.rrV.request.show_object(history_item.request)
            self.kbbrowser.rrV.response.show_object(history_item.response)

            # Don't forget to highlight if necessary
            severity = instance.get_severity()
            for s in instance.get_to_highlight():
                self.kbbrowser.rrV.response.highlight(s, severity)

        else:
Beispiel #15
0
class KBBrowser(entries.RememberingHPaned):
    """Show the Knowledge Base, with the filter and the tree.

    :author: Facundo Batista <facundobatista =at= taniquetil.com.ar>
    """
    def __init__(self, w3af):
        super(KBBrowser, self).__init__(w3af, "pane-kbbrowser", 250)

        # Internal variables:
        # Save the request and response ids to be used in the page control
        self.req_res_ids = []
        # This is to search the DB and print the different request and responses
        # as they are requested from the page control, "page_change" method.
        self._historyItem = HistoryItem()

        # the filter to the tree
        filterbox = gtk.HBox()
        self.filters = {}

        def make_but(label, signal, initial):
            but = gtk.CheckButton(label)
            but.set_active(initial)
            but.connect('clicked', self.type_filter, signal)
            self.filters[signal] = initial
            but.show()
            filterbox.pack_start(but, expand=False, fill=False, padding=2)
        make_but('Vulnerability', 'vuln', True)
        make_but('Information', 'info', True)
        filterbox.show()

        # the kb tree
        self.kbtree = FullKBTree(w3af, self, self.filters)

        # all in the first pane
        kbtree_scrollwin = gtk.ScrolledWindow()
        kbtree_scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        kbtree_scrollwin.add(self.kbtree)
        kbtree_scrollwin.show()

        # the filter and tree box
        treebox = gtk.VBox()
        treebox.pack_start(filterbox, expand=False, fill=False)
        treebox.pack_start(kbtree_scrollwin)
        treebox.show()

        # the vulnerability information
        summary = self.get_notebook_summary(w3af)
        description = self.get_notebook_description()

        self.vuln_notebook = gtk.Notebook()
        self.vuln_notebook.append_page(summary, gtk.Label('Summary'))
        self.vuln_notebook.append_page(description, gtk.Label('Description'))
        self.vuln_notebook.set_current_page(0)
        self.vuln_notebook.show()

        # pack & show
        self.pack1(treebox)
        self.pack2(self.vuln_notebook)
        self.show()

    def get_notebook_description(self):
        # Make the HTML viewable area
        self.description = webkit.WebView()

        # Disable the plugins for the webview
        ws = self.description.get_settings()
        ws.set_property('enable-plugins', False)
        self.description.set_settings(ws)
        self.description.show()

        desc_scroll = gtk.ScrolledWindow()
        desc_scroll.add(self.description)
        desc_scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        desc_scroll.show()

        return desc_scroll

    def get_notebook_summary(self, w3af):
        summary_tv = gtk.TextView()
        summary_tv.set_editable(False)
        summary_tv.set_cursor_visible(False)
        summary_tv.set_wrap_mode(gtk.WRAP_WORD)
        self.explanation = summary_tv.get_buffer()
        summary_tv.show()

        summary_scrollwin = gtk.ScrolledWindow()
        summary_scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        summary_scrollwin.add_with_viewport(summary_tv)
        summary_scrollwin.show()

        # The request/response viewer
        self.rrV = ReqResViewer(w3af, withAudit=False)
        self.rrV.set_sensitive(False)

        # Create the title label to show the request id
        self.title0 = gtk.Label()
        self.title0.show()

        # Create page changer to handle info/vuln objects that have MORE THAN
        # ONE related request/response
        self.pagesControl = entries.PagesControl(w3af, self.page_change, 0)
        self.pagesControl.deactivate()
        self.page_change(0)
        center_box = gtk.HBox()
        center_box.pack_start(self.pagesControl, True, False)

        # Title, request/response and paginator all go together in a vbox
        http_data_vbox = gtk.VBox()
        http_data_vbox.pack_start(self.title0, False, True)
        http_data_vbox.pack_start(self.rrV, True, True)
        http_data_vbox.pack_start(center_box, False, False)

        # and show
        http_data_vbox.show()
        self.pagesControl.show()
        center_box.show()

        # The summary and http data go in a vbox too
        summary_data_vbox = entries.RememberingVPaned(w3af,
                                                      'pane-kbbexplainview',
                                                      100)
        summary_data_vbox.pack1(summary_scrollwin)
        summary_data_vbox.pack2(http_data_vbox)
        summary_data_vbox.show()

        return summary_data_vbox

    def type_filter(self, button, ptype):
        """Changes the filter of the KB in the tree."""
        self.filters[ptype] = button.get_active()
        self.kbtree.set_filter(self.filters)

    def page_change(self, page):
        """
        Handle the page change in the page control.
        """
        # Only do something if I have a list of request and responses
        if self.req_res_ids:
            request_id = self.req_res_ids[page]
            try:
                historyItem = self._historyItem.read(request_id)
            except:
                # the request brought problems
                self.rrV.request.clear_panes()
                self.rrV.response.clear_panes()
                self.rrV.set_sensitive(False)
                self.title0.set_markup("<b>Error</b>")
            else:
                self.title0.set_markup("<b>Id: %d</b>" % request_id)
                self.rrV.request.show_object(historyItem.request)
                self.rrV.response.show_object(historyItem.response)
                self.rrV.set_sensitive(True)
Beispiel #16
0
    def _write_findings_to_xml(self):
        """
        Write all the findings to the XML file
        :return: None, we write the data to the XML
        """
        # HistoryItem to get requests/responses
        req_history = HistoryItem()

        for i in kb.kb.get_all_findings():
            message_node = self._xml.createElement('vulnerability')

            message_node.setAttribute('severity', xml_str(i.get_severity()))
            message_node.setAttribute('method', xml_str(i.get_method()))
            message_node.setAttribute('url', xml_str(i.get_url()))
            message_node.setAttribute('var', xml_str(i.get_token_name()))
            message_node.setAttribute('name', xml_str(i.get_name()))
            message_node.setAttribute('plugin', xml_str(i.get_plugin_name()))

            # Wrap description in a <description> element and put it above the
            # request/response elements
            desc_str = xml_str(i.get_desc(with_id=False))
            description_node = self._xml.createElement('description')
            description = self._xml.createTextNode(desc_str)
            description_node.appendChild(description)
            message_node.appendChild(description_node)

            # If there is information from the vulndb, then we should write it
            if i.has_db_details():
                desc_str = xml_str(i.get_long_description())
                description_node = self._xml.createElement('long-description')
                description = self._xml.createTextNode(desc_str)
                description_node.appendChild(description)
                message_node.appendChild(description_node)

                fix_str = xml_str(i.get_fix_guidance())
                fix_node = self._xml.createElement('fix-guidance')
                fix = self._xml.createTextNode(fix_str)
                fix_node.appendChild(fix)
                message_node.appendChild(fix_node)

                fix_effort_str = xml_str(i.get_fix_effort())
                fix_node = self._xml.createElement('fix-effort')
                fix = self._xml.createTextNode(fix_effort_str)
                fix_node.appendChild(fix)
                message_node.appendChild(fix_node)

                if i.get_references():
                    references_node = self._xml.createElement('references')

                    for ref in i.get_references():
                        ref_node = self._xml.createElement('reference')
                        ref_node.setAttribute('title', xml_str(ref.title))
                        ref_node.setAttribute('url', xml_str(ref.url))
                        references_node.appendChild(ref_node)

                    message_node.appendChild(references_node)

            if i.get_id():
                message_node.setAttribute('id', str(i.get_id()))
                # Wrap all transactions in a http-transactions node
                transaction_set = self._xml.createElement('http-transactions')
                message_node.appendChild(transaction_set)

                for request_id in i.get_id():
                    try:
                        details = req_history.read(request_id)
                    except DBException:
                        msg = 'Failed to retrieve request with id %s from DB.'
                        print(msg % request_id)
                        continue

                    # Wrap the entire http transaction in a single block
                    action_set = self._xml.createElement('http-transaction')
                    action_set.setAttribute('id', str(request_id))
                    transaction_set.appendChild(action_set)

                    request_node = self._xml.createElement('http-request')
                    self.report_http_action(request_node, details.request)
                    action_set.appendChild(request_node)

                    response_node = self._xml.createElement('http-response')
                    self.report_http_action(response_node, details.response)
                    action_set.appendChild(response_node)

            self._top_elem.appendChild(message_node)