def guess_plugin(self, plugin_name): """Check for the existence of the named plugin""" path_nodes, version_nodes, all_versions = \ wadt.loadTables(wac.getDbPath(self.app_name, plugin_name), False) self.error_page_fingerprint = wafu.identify_error_page(self.url) for file in wafu.pick_indicator_files(version_nodes, all_versions): try: #TODO: factor out construction of path to plugin files... #not all plugin dirs can be found simple appending url = self.url + plugin_name + file #self.logger.logExtraInfo(" Trying " + url + "...") data = wafu.urlread_spoof_ua(url) #Check for custom 404 if wafu.compare_to_error_page(self.error_page_fingerprint, data): return False #self.logger.logExtraInfo("found!") return True break except urllib2.URLError, e: #self.logger.logExtraInfo("URLError: %s" % e) pass except HTTPException, e2: #self.logger.logExtraInfo("HTTPError: %s" % e2) pass
def guess_app(self, app_name): """Probe a small number of paths to verify the existence (but not the version) of a particular app """ if not self.error_page_fingerprint and not self.already_checked_for_error_page: print "WARN: Fetching error page because it was not available" self.error_page_fingerprint = wafu.identify_error_page(self.url) self.already_checked_for_error_page = True path_nodes, version_nodes, all_versions = wadt.loadTables(wac.getDbPath(app_name), printStats=False) for file in wac.APP_CONFIG[app_name]["indicatorFiles"]: possible_vers = self.fingerprint_file(file, path_nodes, version_nodes, all_versions) if possible_vers: return True return False
def guess_apps(self, app_list=None): """Probe a small number of indicator files for each supported webapp to quickly check for existence, but not version. """ possible_apps = [] if not self.error_page_fingerprint and not self.already_checked_for_error_page: self.error_page_fingerprint = wafu.identify_error_page(self.url) self.already_checked_for_error_page = True if not app_list: app_list = wac.APP_CONFIG.keys() for app in app_list: if self.guess_app(app): possible_apps.append(app) if self._host_down_errors >= HOST_DOWN_THRESHOLD: break return possible_apps
def fingerprint(self): """Select num_probes most useful paths, and fetch them from the site at url. Return an ordered list of possible versions or []. """ self._load_db() paths = wafu.pick_fingerprint_files(self.path_nodes, self.all_versions) self.logger.logStartFingerprint(self.url, self.app_name) self.error_page_fingerprint = wafu.identify_error_page(self.url) possible_vers = [] for path in paths[:self.num_probes]: curr_vers = self.fingerprint_file(path) if curr_vers: possible_vers.append(curr_vers) if self._host_down_errors >= HOST_DOWN_THRESHOLD: break ver_set = wafu.collapse_version_possibilities(possible_vers) self.ver_list = list(ver_set) #if more than one possibility, try to narrow it by winnowing! if len(self.ver_list) > 1 and self.winnow: print "ver_list before winnowing:" for v in self.ver_list: print v.vstring print "\n" self.winnow_versions(possible_vers) ver_set = wafu.collapse_version_possibilities(possible_vers) self.ver_list = list(ver_set) self.ver_list.sort() if len(self.ver_list) > 1: self.best_guess = wafu.pick_likely_version(self.ver_list) elif len(self.ver_list) == 1: self.best_guess = self.ver_list[0] else: self.best_guess = None self.logger.logFinishFingerprint(self.ver_list, self.best_guess) return self.ver_list