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 _initReqResViewer(self, mainvbox): """Create the req/res viewer.""" self._req_res_viewer = ReqResViewer(self.w3af, editableRequest=False, editableResponse=False) self._req_res_viewer.set_sensitive(False) # Create the req/res selector (when a search with more # than one result is done, this window appears) self._sw = gtk.ScrolledWindow() self._sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) self._sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self._lstore = gtk.ListStore(gobject.TYPE_UINT, gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_UINT, gobject.TYPE_STRING, gobject.TYPE_UINT, gobject.TYPE_STRING, gobject.TYPE_FLOAT) # Create tree view self._lstoreTreeview = gtk.TreeView(self._lstore) self._lstoreTreeview.set_rules_hint(True) self._lstoreTreeview.set_search_column(0) self.__add_columns(self._lstoreTreeview) self._lstoreTreeview.show() self._lstoreTreeview.connect('cursor-changed', self._view_in_req_res_viewer) # Popup menu self._rightButtonMenu = None self._lstoreTreeview.connect('button-press-event', self._popupMenu) # # # Selection # treeselection = self._lstoreTreeview.get_selection() treeselection.set_mode(gtk.SELECTION_MULTIPLE) self._sw.add(self._lstoreTreeview) #self._sw.set_sensitive(False) self._sw.show_all() # I want all sections to be resizable self._vpan = RememberingVPaned(self.w3af, "pane-swandrRV", 100) self._vpan.pack1(self._sw) self._vpan.pack2(self._req_res_viewer) self._vpan.show() mainvbox.pack_start(self._vpan)
def _initReqResViewer(self, mainvbox): """Create the req/res viewer.""" self._req_res_viewer = ReqResViewer(self.w3af, editableRequest=False, editableResponse=False) self._req_res_viewer.set_sensitive(False) # Create the req/res selector (when a search with more # than one result is done, this window appears) self._sw = gtk.ScrolledWindow() self._sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) self._sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self._lstore = gtk.ListStore(gobject.TYPE_UINT, gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_UINT, gobject.TYPE_STRING, gobject.TYPE_UINT, gobject.TYPE_STRING, gobject.TYPE_FLOAT) # Create tree view self._lstoreTreeview = gtk.TreeView(self._lstore) self._lstoreTreeview.set_rules_hint(True) self._lstoreTreeview.set_search_column(0) self.__add_columns(self._lstoreTreeview) self._lstoreTreeview.show() self._lstoreTreeview.connect( 'cursor-changed', self._view_in_req_res_viewer) # Popup menu self._rightButtonMenu = None self._lstoreTreeview.connect('button-press-event', self._popupMenu) # # # Selection # treeselection = self._lstoreTreeview.get_selection() treeselection.set_mode(gtk.SELECTION_MULTIPLE) self._sw.add(self._lstoreTreeview) #self._sw.set_sensitive(False) self._sw.show_all() # I want all sections to be resizable self._vpan = RememberingVPaned(self.w3af, "pane-swandrRV", 100) self._vpan.pack1(self._sw) self._vpan.pack2(self._req_res_viewer) self._vpan.show() mainvbox.pack_start(self._vpan)
def __init__(self, w3af, initial_request=None): super(ManualRequests, self).__init__(w3af, "manualreq", "w3af - Manual Requests", "Manual_Requests") self.w3af = w3af # # Toolbar # self.send_but = entries.SemiStockButton(_("Send"), gtk.STOCK_MEDIA_PLAY, _("Send HTTP request")) self.send_but.connect("clicked", self._send) self.send_but.show() # Fix content length checkbox self._fix_content_len_cb = gtk.CheckButton('Fix content length header') self._fix_content_len_cb.set_active(True) self._fix_content_len_cb.show() # request-response viewer self.reqresp = ReqResViewer(w3af, [self.send_but.set_sensitive], withManual=False, editableRequest=True) self.reqresp.response.set_sensitive(False) self.vbox.pack_start(self.reqresp, True, True) self.vbox.pack_start(self._fix_content_len_cb, False, False) self.vbox.pack_start(self.send_but, False, False) # Add a default request if initial_request is None: self.reqresp.request.show_raw(MANUAL_REQUEST_EXAMPLE, '') else: initial_up, initial_dn = initial_request self.reqresp.request.show_raw(initial_up, initial_dn) # Show all! self.show()
class httpLogTab(RememberingHPaned): """ A tab that shows all HTTP requests and responses made by the framework. :author: Andres Riancho ([email protected]) """ def __init__(self, w3af, padding=10, time_refresh=False): """Init object.""" super(httpLogTab, self).__init__(w3af, "pane-httplogtab", 300) self.w3af = w3af self._padding = padding self._lastId = 0 self._historyItem = HistoryItem() if time_refresh: gobject.timeout_add(1000, self.refresh_results) # Create the main container mainvbox = gtk.VBox() mainvbox.set_spacing(self._padding) # Add the menuHbox, Req/Res viewer and the R/R selector on the bottom self._initSearchBox(mainvbox) self._initFilterBox(mainvbox) self._initReqResViewer(mainvbox) mainvbox.show() # Add everything self.add(mainvbox) self.show() def _initReqResViewer(self, mainvbox): """Create the req/res viewer.""" self._req_res_viewer = ReqResViewer(self.w3af, editableRequest=False, editableResponse=False) self._req_res_viewer.set_sensitive(False) # Create the req/res selector (when a search with more # than one result is done, this window appears) self._sw = gtk.ScrolledWindow() self._sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) self._sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self._lstore = gtk.ListStore(gobject.TYPE_UINT, gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_UINT, gobject.TYPE_STRING, gobject.TYPE_UINT, gobject.TYPE_STRING, gobject.TYPE_FLOAT) # Create tree view self._lstoreTreeview = gtk.TreeView(self._lstore) self._lstoreTreeview.set_rules_hint(True) self._lstoreTreeview.set_search_column(0) self.__add_columns(self._lstoreTreeview) self._lstoreTreeview.show() self._lstoreTreeview.connect('cursor-changed', self._view_in_req_res_viewer) # Popup menu self._rightButtonMenu = None self._lstoreTreeview.connect('button-press-event', self._popupMenu) # # # Selection # treeselection = self._lstoreTreeview.get_selection() treeselection.set_mode(gtk.SELECTION_MULTIPLE) self._sw.add(self._lstoreTreeview) #self._sw.set_sensitive(False) self._sw.show_all() # I want all sections to be resizable self._vpan = RememberingVPaned(self.w3af, "pane-swandrRV", 100) self._vpan.pack1(self._sw) self._vpan.pack2(self._req_res_viewer) self._vpan.show() mainvbox.pack_start(self._vpan) def _popupMenu(self, tv, event): """Generate and show popup menu.""" if event.button != 3: return # creates the whole menu only once if self._rightButtonMenu is None: gm = gtk.Menu() self._rightButtonMenu = gm # the items e = gtk.MenuItem(_("Delete selected items")) e.connect('activate', self._deleteSelected) gm.append(e) gm.show_all() else: gm = self._rightButtonMenu gm.popup(None, None, None, event.button, event.time) return True def _deleteSelected(self, widg=None): """Delete selected transactions.""" ids = [] iters = [] sel = self._lstoreTreeview.get_selection() (model, pathlist) = sel.get_selected_rows() for path in pathlist: iters.append(self._lstore.get_iter(path)) itemNumber = path[0] iid = self._lstore[itemNumber][0] ids.append(iid) for i in iters: self._lstore.remove(i) # TODO Move this action to separate thread for iid in ids: self._historyItem.delete(iid) def _initSearchBox(self, mainvbox): """Init Search box.""" # The search entry self._searchText = gtk.Entry() self._searchText.connect("activate", self.find_request_response) # The button that is used to advanced search filterBtn = gtk.ToggleButton(label=_("_Filter Options")) filterBtn.connect("toggled", self._showHideFilterBox) filterImg = gtk.Image() filterImg.set_from_stock(gtk.STOCK_FIND, gtk.ICON_SIZE_MENU) filterBtn.set_image(filterImg) # Clear button close = gtk.Image() close.set_from_stock(gtk.STOCK_CLEAR, gtk.ICON_SIZE_MENU) clearBox = gtk.EventBox() clearBox.add(close) clearBox.connect("button-release-event", self._showAllRequestResponses) # Create the container that has the menu menuHbox = gtk.HBox() menuHbox.set_spacing(self._padding) menuHbox.pack_start(gtk.Label(_("Search:")), False) menuHbox.pack_start(self._searchText) menuHbox.pack_start(clearBox, False) menuHbox.pack_start(filterBtn, False) menuHbox.show_all() mainvbox.pack_start(menuHbox, False, True) def _initFilterBox(self, mainvbox): """Init advanced search options.""" self._advSearchBox = gtk.HBox() self._advSearchBox.set_spacing(self._padding) self.pref = FilterOptions(self) # Filter options self._filterMethods = [ ('GET', 'GET', False), ('POST', 'POST', False), ] filterMethods = OptionList() for method in self._filterMethods: filterMethods.add( opt_factory(method[0], method[2], method[1], "boolean")) self.pref.add_section('methods', _('Request Method'), filterMethods) filterId = OptionList() filterId.add(opt_factory("min", "0", "Min ID", "string")) filterId.add(opt_factory("max", "0", "Max ID", "string")) self.pref.add_section('trans_id', _('Transaction ID'), filterId) filterCodes = OptionList() codes = [ ("1xx", "1xx", False), ("2xx", "2xx", False), ("3xx", "3xx", False), ("4xx", "4xx", False), ("5xx", "5xx", False), ] for code in codes: filterCodes.add(opt_factory(code[0], code[2], code[1], "boolean")) self.pref.add_section('codes', _('Response Code'), filterCodes) filterMisc = OptionList() filterMisc.add(opt_factory("tag", False, "Tag", "boolean")) filterMisc.add( opt_factory("has_qs", False, "Request has Query String", "boolean")) self.pref.add_section('misc', _('Misc'), filterMisc) filterTypes = OptionList() self._filterTypes = [ ('html', 'HTML', False), ('javascript', 'JavaScript', False), ('image', 'Images', False), ('flash', 'Flash', False), ('css', 'CSS', False), ('text', 'Text', False), ] for filterType in self._filterTypes: filterTypes.add( opt_factory(filterType[0], filterType[2], filterType[1], "boolean")) self.pref.add_section('types', _('Response Content Type'), filterTypes) filterSize = OptionList() filterSize.add(opt_factory("resp_size", False, "Not Null", "boolean")) self.pref.add_section('sizes', _('Response Size'), filterSize) self.pref.show() self._advSearchBox.pack_start(self.pref, False, False) self._advSearchBox.hide_all() mainvbox.pack_start(self._advSearchBox, False, False) def __add_columns(self, treeview): """Add columns to main log table.""" model = treeview.get_model() # Column for id's column = gtk.TreeViewColumn(_('ID'), gtk.CellRendererText(), text=0) column.set_sort_column_id(0) treeview.append_column(column) # Column for bookmark #TODO: Find a better way to do this. The "B" and the checkbox aren't nice #what we aim for is something like the stars in gmail. """ renderer = gtk.CellRendererToggle() renderer.set_property('activatable', True) renderer.connect('toggled', self.toggle_bookmark, model) column = gtk.TreeViewColumn(_('B'), renderer) column.add_attribute(renderer, "active", 1) column.set_sort_column_id(1) treeview.append_column(column) """ # Column for METHOD column = gtk.TreeViewColumn(_('Method'), gtk.CellRendererText(), text=2) column.set_sort_column_id(2) treeview.append_column(column) # Column for URI renderer = gtk.CellRendererText() renderer.set_property('ellipsize', pango.ELLIPSIZE_END) column = gtk.TreeViewColumn('URI', renderer, text=3) column.set_sort_column_id(3) column.set_expand(True) column.set_resizable(True) treeview.append_column(column) # Column for Tag renderer = gtk.CellRendererText() #renderer.set_property('ellipsize', pango.ELLIPSIZE_END) renderer.set_property('editable', True) renderer.connect('edited', self.edit_tag, model) column = gtk.TreeViewColumn(_('Tag'), renderer, text=4) column.set_sort_column_id(4) column.set_resizable(True) column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) treeview.append_column(column) extColumns = [ (5, _('Code')), (6, _('Message')), (7, _('Content-Length')), (8, _('Content-Type')), (9, _('Time (ms)')), ] for n, title in extColumns: column = gtk.TreeViewColumn(title, gtk.CellRendererText(), text=n) column.set_sort_column_id(n) treeview.append_column(column) def toggle_bookmark(self, cell, path, model): """Toggle bookmark.""" model[path][1] = not model[path][1] historyItem = HistoryItem() historyItem.load(model[path][0]) historyItem.toggle_mark(True) return def edit_tag(self, cell, path, new_text, model): """Edit tag.""" model[path][4] = new_text historyItem = HistoryItem() historyItem.load(model[path][0]) historyItem.update_tag(new_text, True) return def _showHideFilterBox(self, widget): """Show/hide advanced options.""" if not widget.get_active(): self._advSearchBox.hide_all() else: self._advSearchBox.show_all() def _showAllRequestResponses(self, widget=None, event=None): """Show all results.""" self._searchText.set_text("") try: self.find_request_response() except BaseFrameworkException as w3: self._empty_results() return def refresh_results(self): """ TODO: IMPROVEMENT: The find_request_response will read all items from the DB again. If there are no new requests BUT we're already showing 1K of them, all will be read. Not good for performance. """ self.find_request_response(refresh=True) return True def find_request_response(self, widget=None, refresh=False): """Find entries (req/res).""" searchText = self._searchText.get_text() searchText = searchText.strip() search_data = [] # # Search part # if searchText: likePieces = [('url', "%" + searchText + "%", 'like'), ('tag', "%" + searchText + "%", 'like')] search_data.append((likePieces, 'OR')) # # Filter part # # Codes codes = self.pref.get_options('codes') filterCodes = [] for opt in codes: if opt.get_value(): codef = opt.get_name() filterCodes.append(('codef', int(codef[0]), '=')) search_data.append((filterCodes, 'OR')) # IDs try: minId = int(self.pref.get_value('trans_id', 'min')) except: minId = 0 try: maxId = int(self.pref.get_value('trans_id', 'max')) except: maxId = 0 if maxId > 0: search_data.append(('id', maxId, "<")) if minId > 0: search_data.append(('id', minId, ">")) if refresh: search_data.append(('id', self._lastId, ">")) # Sizes if self.pref.get_value('sizes', 'resp_size'): search_data.append(('response_size', 0, ">")) # Tags if self.pref.get_value('misc', 'tag'): search_data.append(('tag', '', "!=")) # has_query_string if self.pref.get_value('misc', 'has_qs'): search_data.append(('has_qs', 0, ">")) # Content type filterTypes = [] for filterType in self._filterTypes: if self.pref.get_value('types', filterType[0]): filterTypes.append( ('content_type', "%" + filterType[0] + "%", 'like')) search_data.append((filterTypes, 'OR')) # Method filterMethods = [] for method in self._filterMethods: if self.pref.get_value('methods', method[0]): filterTypes.append(('method', method[0], '=')) search_data.append((filterMethods, 'OR')) try: # Please see the 5000 below searchResultObjects = self._historyItem.find(search_data, result_limit=5001, order_data=[("id", "") ]) except BaseFrameworkException, w3: self._empty_results() return if len(searchResultObjects) == 0: if not refresh: self._empty_results() return # Please see the 5001 above elif len(searchResultObjects) > 5000: self._empty_results() msg = _('The search you performed returned too many results (') +\ str(len(searchResultObjects)) + ').\n' msg += _('Please refine your search and try again.') self._show_message('Too many results', msg) return else: # show the results in the list view (when first row is selected # that just triggers the req/resp filling. lastItem = searchResultObjects[-1] self._lastId = int(lastItem.id) self._show_list_view(searchResultObjects, appendMode=refresh) self._sw.set_sensitive(True) self._req_res_viewer.set_sensitive(True) if not refresh: self._lstoreTreeview.set_cursor((0, )) return
def __init__(self, w3af): """Constructor.""" super(ProxiedRequests, self).__init__(w3af, 'proxytool', _('w3af - Proxy'), 'Using_the_Proxy', onDestroy=self._close) self.w3af = w3af self.def_padding = 5 self._uimanager = gtk.UIManager() accelgroup = self._uimanager.get_accel_group() self.add_accel_group(accelgroup) actiongroup = gtk.ActionGroup('UIManager') actiongroup.add_actions([ ('Help', gtk.STOCK_HELP, _('_Help'), None, _('Help regarding this window'), self.open_help), ('Drop', gtk.STOCK_CANCEL, _('_Drop Request'), None, _('Drop request'), self._drop), ('Send', gtk.STOCK_YES, _('_Send Request'), None, _('Send request'), self._send), ('Next', gtk.STOCK_GO_FORWARD, _('_Next Request'), None, _('Move to the next request'), self._next), ]) actiongroup.add_toggle_actions([ # xml_name, icon, real_menu_text, accelerator, tooltip, # callback, initial_flag ('TrapReq', gtk.STOCK_JUMP_TO, _('_Trap Requests'), None, _('Trap requests'), self._toggle_trap, False), ]) # Finish the toolbar self._uimanager.insert_action_group(actiongroup, 0) self._uimanager.add_ui_from_string(ui_proxy_menu) toolbar = self._uimanager.get_widget('/Toolbar') self.bt_drop = toolbar.get_nth_item(2) self.bt_send = toolbar.get_nth_item(3) self.bt_next = toolbar.get_nth_item(4) self.bt_next.set_sensitive(False) self.bt_send.set_sensitive(False) self.bt_drop.set_sensitive(False) separat = toolbar.get_nth_item(5) separat.set_draw(False) separat.set_expand(True) self.vbox.pack_start(toolbar, False) self.vbox.show() toolbar.show() # Request-response viewer self._init_options() self._prev_ip_port = None # We need to make widget (split or tabbed) firstly self._layout = self.pref.get_value('proxy', 'trap_view') self.reqresp = ReqResViewer( w3af, [self.bt_drop.set_sensitive, self.bt_send.set_sensitive], editableRequest=True, layout=self._layout) self.reqresp.set_sensitive(False) vbox = gtk.VBox() vbox.pack_start(self.reqresp, True, True) vbox.show() # Notebook self.nb = gtk.Notebook() tabs = [] # Intercept tmp = gtk.Label(_("_Intercept")) tmp.set_use_underline(True) self.nb.append_page(vbox, tmp) tabs.append('Intercept') # History self.httplog = httpLogTab.httpLogTab(w3af, time_refresh=True) tmp = gtk.Label(_("_History")) tmp.set_use_underline(True) self.nb.append_page(self.httplog, tmp) tabs.append('History') # Options tmp = gtk.Label(_("_Options")) tmp.set_use_underline(True) self.nb.append_page(self.pref, tmp) tabs.append('Options') self.vbox.pack_start(self.nb, True, True, padding=self.def_padding) self.nb.show() # Go to Home Tab self.nb.set_current_page( tabs.index(self.pref.get_value('proxy', 'home_tab'))) # Status bar for messages self.status_bar = StatusBar() self.vbox.pack_start(self.status_bar, False, False) self.status_bar.show() self.proxy = None # Finish it self.fuzzable = None self.waiting_requests = False self.keep_checking = False self.reload_options() gobject.timeout_add(200, self._supervise_requests) self.show()
class ProxiedRequests(entries.RememberingWindow): """Proxies the HTTP requests, allowing modifications. :author: Facundo Batista <facundobatista =at= taniquetil.com.ar> """ def __init__(self, w3af): """Constructor.""" super(ProxiedRequests, self).__init__(w3af, 'proxytool', _('w3af - Proxy'), 'Using_the_Proxy', onDestroy=self._close) self.w3af = w3af self.def_padding = 5 self._uimanager = gtk.UIManager() accelgroup = self._uimanager.get_accel_group() self.add_accel_group(accelgroup) actiongroup = gtk.ActionGroup('UIManager') actiongroup.add_actions([ ('Help', gtk.STOCK_HELP, _('_Help'), None, _('Help regarding this window'), self.open_help), ('Drop', gtk.STOCK_CANCEL, _('_Drop Request'), None, _('Drop request'), self._drop), ('Send', gtk.STOCK_YES, _('_Send Request'), None, _('Send request'), self._send), ('Next', gtk.STOCK_GO_FORWARD, _('_Next Request'), None, _('Move to the next request'), self._next), ]) actiongroup.add_toggle_actions([ # xml_name, icon, real_menu_text, accelerator, tooltip, # callback, initial_flag ('TrapReq', gtk.STOCK_JUMP_TO, _('_Trap Requests'), None, _('Trap requests'), self._toggle_trap, False), ]) # Finish the toolbar self._uimanager.insert_action_group(actiongroup, 0) self._uimanager.add_ui_from_string(ui_proxy_menu) toolbar = self._uimanager.get_widget('/Toolbar') self.bt_drop = toolbar.get_nth_item(2) self.bt_send = toolbar.get_nth_item(3) self.bt_next = toolbar.get_nth_item(4) self.bt_next.set_sensitive(False) self.bt_send.set_sensitive(False) self.bt_drop.set_sensitive(False) separat = toolbar.get_nth_item(5) separat.set_draw(False) separat.set_expand(True) self.vbox.pack_start(toolbar, False) self.vbox.show() toolbar.show() # Request-response viewer self._init_options() self._prev_ip_port = None # We need to make widget (split or tabbed) firstly self._layout = self.pref.get_value('proxy', 'trap_view') self.reqresp = ReqResViewer( w3af, [self.bt_drop.set_sensitive, self.bt_send.set_sensitive], editableRequest=True, layout=self._layout) self.reqresp.set_sensitive(False) vbox = gtk.VBox() vbox.pack_start(self.reqresp, True, True) vbox.show() # Notebook self.nb = gtk.Notebook() tabs = [] # Intercept tmp = gtk.Label(_("_Intercept")) tmp.set_use_underline(True) self.nb.append_page(vbox, tmp) tabs.append('Intercept') # History self.httplog = httpLogTab.httpLogTab(w3af, time_refresh=True) tmp = gtk.Label(_("_History")) tmp.set_use_underline(True) self.nb.append_page(self.httplog, tmp) tabs.append('History') # Options tmp = gtk.Label(_("_Options")) tmp.set_use_underline(True) self.nb.append_page(self.pref, tmp) tabs.append('Options') self.vbox.pack_start(self.nb, True, True, padding=self.def_padding) self.nb.show() # Go to Home Tab self.nb.set_current_page( tabs.index(self.pref.get_value('proxy', 'home_tab'))) # Status bar for messages self.status_bar = StatusBar() self.vbox.pack_start(self.status_bar, False, False) self.status_bar.show() self.proxy = None # Finish it self.fuzzable = None self.waiting_requests = False self.keep_checking = False self.reload_options() gobject.timeout_add(200, self._supervise_requests) self.show() def _init_options(self): """Init options.""" self.like_initial = True self.pref = ConfigOptions(self.w3af, self, 'proxy_options') # Proxy options proxy_options = OptionList() d = _('Proxy IP address and port number') h = _( 'Local IP address where the proxy will listen for HTTP requests.') o = opt_factory('ipport', '127.0.0.1:8080', d, option_types.IPPORT, help=h) proxy_options.add(o) d = _('Regular expression for URLs to intercept') h = _('Regular expression to match against the URLs of HTTP requests' ' to decide if the request should be intercepted for analysis/' 'modifications or not.') o = opt_factory('trap', ".*", d, option_types.REGEX, help=h) proxy_options.add(o) d = _("HTTP methods to intercept") h = _('Comma separated list of HTTP methods to intercept') o = opt_factory('methodtrap', "GET,POST", d, option_types.LIST, help=h) proxy_options.add(o) d = _("Ignored extensions") h = _('Filename extensions that will NOT be intercepted') default_value = ".*\.(gif|jpg|png|css|js|ico|swf|axd|tif)$" o = opt_factory("notrap", default_value, d, option_types.REGEX, help=h) proxy_options.add(o) d = _("View mode for intercept tab") views = ('Split', 'Tabbed') o = opt_factory("trap_view", views, d, option_types.COMBO) proxy_options.add(o) d = _("Home tab") homes = ['Intercept', 'History', 'Options'] o = opt_factory("home_tab", homes, d, option_types.COMBO) proxy_options.add(o) self.pref.add_section('proxy', _('Proxy options'), proxy_options) # HTTP editor options editor_options = OptionList() o = opt_factory("wrap", True, _("Wrap long lines"), "boolean") editor_options.add(o) o = opt_factory("highlight_current_line", True, _("Highlight current line"), "boolean") editor_options.add(o) o = opt_factory("highlight_syntax", True, _("Highlight syntax"), "boolean") editor_options.add(o) o = opt_factory("display_line_num", True, _("Display line numbers"), "boolean") editor_options.add(o) self.pref.add_section('editor', _('HTTP editor options'), editor_options) # Load values from configfile self.pref.load_values() self.pref.show() def config_changed(self, like_initial): """Propagates the change from the options. :param like_initial: If the config is like the initial one """ self.like_initial = like_initial def reload_options(self): """Reload options. 1. Stop proxy 2. Try to start proxy with new params 3. If can't => alert 4. If everything is ok then start proxy 5. Set Trap options 6. Save options """ new_port = self.pref.get_value('proxy', 'ipport') if new_port != self._prev_ip_port: self.w3af.mainwin.sb(_("Stopping local proxy")) if self.proxy: self.proxy.stop() try: self._start_proxy() except ProxyException: # Ups, port looks already used..:( # Let's show alert and focus Options tab self.w3af.mainwin.sb(_("Failed to start local proxy")) self.fuzzable = None self.waiting_requests = False self.keep_checking = False # Focus Options tab self.nb.set_current_page(2) return else: self.fuzzable = None self.waiting_requests = True self.keep_checking = True # Config test try: self.proxy.set_what_to_trap(self.pref.get_value('proxy', 'trap')) self.proxy.set_what_not_to_trap( self.pref.get_value('proxy', 'notrap')) self.proxy.set_methods_to_trap( self.pref.get_value('proxy', 'methodtrap')) except BaseFrameworkException as w3: self.show_alert(_("Invalid configuration!\n" + str(w3))) self._prev_ip_port = new_port httpeditor = self.reqresp.request.get_view_by_id('HttpRawView') httpeditor.set_show_line_numbers( self.pref.get_value('editor', 'display_line_num')) httpeditor.set_highlight_current_line( self.pref.get_value('editor', 'highlight_current_line')) httpeditor.set_highlight_syntax( self.pref.get_value('editor', 'highlight_syntax')) httpeditor.set_wrap(self.pref.get_value('editor', 'wrap')) self.pref.save() if self._layout != self.pref.get_value('proxy', 'trap_view'): self.show_alert( _('Some of options will take effect after you' ' restart proxy tool')) def show_alert(self, msg): dlg = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, msg) dlg.run() dlg.destroy() def _start_proxy(self, ip=None, port=None, silent=False): """Starts the proxy.""" if not ip: ipport = self.pref.get_value('proxy', 'ipport') ip, port = ipport.split(":") self.w3af.mainwin.sb(_("Starting local proxy")) try: self.proxy = InterceptProxy(ip, int(port), self.w3af.uri_opener) except ProxyException as w3: if not silent: self.show_alert(_(str(w3))) raise w3 else: self.proxy.start() def _supervise_requests(self, *args): """Supervise if there are requests to show. :return: True to gobject to keep calling it, False when all is done. """ if self.waiting_requests: req = self.proxy.get_trapped_request() if req is not None: self.waiting_requests = False self.fuzzable = req self.reqresp.request.set_sensitive(True) self.reqresp.request.show_object(req) self.bt_drop.set_sensitive(True) self.bt_send.set_sensitive(True) self.bt_next.set_sensitive(True) return self.keep_checking def _drop(self, widg): """Discards the actual request. :param widget: who sent the signal. """ self.reqresp.request.clear_panes() self.reqresp.request.set_sensitive(False) self.waiting_requests = True self.proxy.drop_request(self.fuzzable) def _send(self, widg): """Sends the request through the proxy. :param widg: who sent the signal. """ request = self.reqresp.request.get_object() # if nothing to send if not request: return headers = request.dump_request_head() data = request.get_data() if data: data = str(data) try: http_resp = helpers.coreWrap(self.proxy.on_request_edit_finished, self.fuzzable, headers, data) except BaseFrameworkException: return else: self.fuzzable = None self.reqresp.response.set_sensitive(True) self.reqresp.response.show_object(http_resp) self.reqresp.focus_response() self.bt_drop.set_sensitive(False) self.bt_send.set_sensitive(False) def _next(self, widg): """Moves to the next request. :param widg: who sent the signal. """ resp = self.reqresp.response.get_object() # If there is request to send, let's send it first if not resp: self._send(None) self.reqresp.request.clear_panes() self.reqresp.request.set_sensitive(False) self.reqresp.response.clear_panes() self.reqresp.response.set_sensitive(False) self.bt_next.set_sensitive(False) self.reqresp.focus_request() self.waiting_requests = True def _close(self): """Closes everything.""" self.keep_checking = False msg = _('Do you want to quit and close the proxy?') 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 False if self.proxy: self.proxy.stop() return True def _toggle_trap(self, widget): """Toggle the trap flag.""" if self.proxy is None: return trapactive = widget.get_active() self.proxy.set_trap(trapactive) status = 'Trap is %s' % ('on' if trapactive else 'off', ) self.status_bar(status) # Send all requests in queue if Intercept is switched off if not trapactive: res = self.reqresp.response.get_object() req = self.reqresp.request.get_object() # If there is request to send, let's send it first if req and not res: self._send(None)
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()
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
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)
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)
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
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()
class httpLogTab(RememberingHPaned): """ A tab that shows all HTTP requests and responses made by the framework. :author: Andres Riancho ([email protected]) """ def __init__(self, w3af, padding=10, time_refresh=False): """Init object.""" super(httpLogTab, self).__init__(w3af, "pane-httplogtab", 300) self.w3af = w3af self._padding = padding self._lastId = 0 self._historyItem = HistoryItem() if time_refresh: gobject.timeout_add(1000, self.refresh_results) # Create the main container mainvbox = gtk.VBox() mainvbox.set_spacing(self._padding) # Add the menuHbox, Req/Res viewer and the R/R selector on the bottom self._initSearchBox(mainvbox) self._initFilterBox(mainvbox) self._initReqResViewer(mainvbox) mainvbox.show() # Add everything self.add(mainvbox) self.show() def _initReqResViewer(self, mainvbox): """Create the req/res viewer.""" self._req_res_viewer = ReqResViewer(self.w3af, editableRequest=False, editableResponse=False) self._req_res_viewer.set_sensitive(False) # Create the req/res selector (when a search with more # than one result is done, this window appears) self._sw = gtk.ScrolledWindow() self._sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) self._sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self._lstore = gtk.ListStore(gobject.TYPE_UINT, gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_UINT, gobject.TYPE_STRING, gobject.TYPE_UINT, gobject.TYPE_STRING, gobject.TYPE_FLOAT) # Create tree view self._lstoreTreeview = gtk.TreeView(self._lstore) self._lstoreTreeview.set_rules_hint(True) self._lstoreTreeview.set_search_column(0) self.__add_columns(self._lstoreTreeview) self._lstoreTreeview.show() self._lstoreTreeview.connect( 'cursor-changed', self._view_in_req_res_viewer) # Popup menu self._rightButtonMenu = None self._lstoreTreeview.connect('button-press-event', self._popupMenu) # # # Selection # treeselection = self._lstoreTreeview.get_selection() treeselection.set_mode(gtk.SELECTION_MULTIPLE) self._sw.add(self._lstoreTreeview) #self._sw.set_sensitive(False) self._sw.show_all() # I want all sections to be resizable self._vpan = RememberingVPaned(self.w3af, "pane-swandrRV", 100) self._vpan.pack1(self._sw) self._vpan.pack2(self._req_res_viewer) self._vpan.show() mainvbox.pack_start(self._vpan) def _popupMenu(self, tv, event): """Generate and show popup menu.""" if event.button != 3: return # creates the whole menu only once if self._rightButtonMenu is None: gm = gtk.Menu() self._rightButtonMenu = gm # the items e = gtk.MenuItem(_("Delete selected items")) e.connect('activate', self._deleteSelected) gm.append(e) gm.show_all() else: gm = self._rightButtonMenu gm.popup(None, None, None, event.button, event.time) return True def _deleteSelected(self, widg=None): """Delete selected transactions.""" ids = [] iters = [] sel = self._lstoreTreeview.get_selection() (model, pathlist) = sel.get_selected_rows() for path in pathlist: iters.append(self._lstore.get_iter(path)) itemNumber = path[0] iid = self._lstore[itemNumber][0] ids.append(iid) for i in iters: self._lstore.remove(i) # TODO Move this action to separate thread for iid in ids: self._historyItem.delete(iid) def _initSearchBox(self, mainvbox): """Init Search box.""" # The search entry self._searchText = gtk.Entry() self._searchText.connect("activate", self.find_request_response) # The button that is used to advanced search filterBtn = gtk.ToggleButton(label=_("_Filter Options")) filterBtn.connect("toggled", self._showHideFilterBox) filterImg = gtk.Image() filterImg.set_from_stock(gtk.STOCK_FIND, gtk.ICON_SIZE_MENU) filterBtn.set_image(filterImg) # Clear button close = gtk.Image() close.set_from_stock(gtk.STOCK_CLEAR, gtk.ICON_SIZE_MENU) clearBox = gtk.EventBox() clearBox.add(close) clearBox.connect("button-release-event", self._showAllRequestResponses) # Create the container that has the menu menuHbox = gtk.HBox() menuHbox.set_spacing(self._padding) menuHbox.pack_start(gtk.Label(_("Search:")), False) menuHbox.pack_start(self._searchText) menuHbox.pack_start(clearBox, False) menuHbox.pack_start(filterBtn, False) menuHbox.show_all() mainvbox.pack_start(menuHbox, False, True) def _initFilterBox(self, mainvbox): """Init advanced search options.""" self._advSearchBox = gtk.HBox() self._advSearchBox.set_spacing(self._padding) self.pref = FilterOptions(self) # Filter options self._filterMethods = [ ('GET', 'GET', False), ('POST', 'POST', False), ] filterMethods = OptionList() for method in self._filterMethods: filterMethods.add( opt_factory(method[0], method[2], method[1], "boolean")) self.pref.add_section('methods', _('Request Method'), filterMethods) filterId = OptionList() filterId.add(opt_factory("min", "0", "Min ID", "string")) filterId.add(opt_factory("max", "0", "Max ID", "string")) self.pref.add_section('trans_id', _('Transaction ID'), filterId) filterCodes = OptionList() codes = [ ("1xx", "1xx", False), ("2xx", "2xx", False), ("3xx", "3xx", False), ("4xx", "4xx", False), ("5xx", "5xx", False), ] for code in codes: filterCodes.add(opt_factory(code[0], code[2], code[1], "boolean")) self.pref.add_section('codes', _('Response Code'), filterCodes) filterMisc = OptionList() filterMisc.add(opt_factory("tag", False, "Tag", "boolean")) filterMisc.add(opt_factory( "has_qs", False, "Request has Query String", "boolean")) self.pref.add_section('misc', _('Misc'), filterMisc) filterTypes = OptionList() self._filterTypes = [ ('html', 'HTML', False), ('javascript', 'JavaScript', False), ('image', 'Images', False), ('flash', 'Flash', False), ('css', 'CSS', False), ('text', 'Text', False), ] for filterType in self._filterTypes: filterTypes.add(opt_factory( filterType[0], filterType[2], filterType[1], "boolean")) self.pref.add_section('types', _('Response Content Type'), filterTypes) filterSize = OptionList() filterSize.add(opt_factory("resp_size", False, "Not Null", "boolean")) self.pref.add_section('sizes', _('Response Size'), filterSize) self.pref.show() self._advSearchBox.pack_start(self.pref, False, False) self._advSearchBox.hide_all() mainvbox.pack_start(self._advSearchBox, False, False) def __add_columns(self, treeview): """Add columns to main log table.""" model = treeview.get_model() # Column for id's column = gtk.TreeViewColumn(_('ID'), gtk.CellRendererText(), text=0) column.set_sort_column_id(0) treeview.append_column(column) # Column for bookmark #TODO: Find a better way to do this. The "B" and the checkbox aren't nice #what we aim for is something like the stars in gmail. """ renderer = gtk.CellRendererToggle() renderer.set_property('activatable', True) renderer.connect('toggled', self.toggle_bookmark, model) column = gtk.TreeViewColumn(_('B'), renderer) column.add_attribute(renderer, "active", 1) column.set_sort_column_id(1) treeview.append_column(column) """ # Column for METHOD column = gtk.TreeViewColumn( _('Method'), gtk.CellRendererText(), text=2) column.set_sort_column_id(2) treeview.append_column(column) # Column for URI renderer = gtk.CellRendererText() renderer.set_property('ellipsize', pango.ELLIPSIZE_END) column = gtk.TreeViewColumn('URI', renderer, text=3) column.set_sort_column_id(3) column.set_expand(True) column.set_resizable(True) treeview.append_column(column) # Column for Tag renderer = gtk.CellRendererText() #renderer.set_property('ellipsize', pango.ELLIPSIZE_END) renderer.set_property('editable', True) renderer.connect('edited', self.edit_tag, model) column = gtk.TreeViewColumn(_('Tag'), renderer, text=4) column.set_sort_column_id(4) column.set_resizable(True) column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) treeview.append_column(column) extColumns = [ (5, _('Code')), (6, _('Message')), (7, _('Content-Length')), (8, _('Content-Type')), (9, _('Time (ms)')), ] for n, title in extColumns: column = gtk.TreeViewColumn(title, gtk.CellRendererText(), text=n) column.set_sort_column_id(n) treeview.append_column(column) def toggle_bookmark(self, cell, path, model): """Toggle bookmark.""" model[path][1] = not model[path][1] historyItem = HistoryItem() historyItem.load(model[path][0]) historyItem.toggle_mark(True) return def edit_tag(self, cell, path, new_text, model): """Edit tag.""" model[path][4] = new_text historyItem = HistoryItem() historyItem.load(model[path][0]) historyItem.update_tag(new_text, True) return def _showHideFilterBox(self, widget): """Show/hide advanced options.""" if not widget.get_active(): self._advSearchBox.hide_all() else: self._advSearchBox.show_all() def _showAllRequestResponses(self, widget=None, event=None): """Show all results.""" self._searchText.set_text("") try: self.find_request_response() except BaseFrameworkException, w3: self._empty_results() return
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()