def run(self, info): # Parse original URL m_url = info.url m_url_parts = info.parsed_url # If file is a javascript, css or image, do not run if info.parsed_url.extension[1:] in ( 'css', 'js', 'jpeg', 'jpg', 'png', 'gif', 'svg') or not m_url_parts.extension: Logger.log_more_verbose("Skipping URL: %s" % m_url) return Logger.log_more_verbose("Bruteforcing URL: %s" % m_url) # # Load wordlist for changing directories # # COMMON m_urls = make_url_changing_folder_name(m_url_parts) # Generates the error page m_error_response = get_error_page(m_url) # Create the matching analyzer try: m_store_info = MatchingAnalyzer(m_error_response.raw_data, min_ratio=0.65) except ValueError, e: Logger.log_error( "There is not information for analyze when creating the matcher: '%s'" % e) return
def recv_info(self, info): # Parse original URL m_url = info.url m_url_parts = info.parsed_url # If file is a javascript, css or image, do not run if info.parsed_url.extension[1:] in ('css', 'js', 'jpeg', 'jpg', 'png', 'gif', 'svg') or not m_url_parts.extension: Logger.log_more_verbose("Skipping URL: %s" % m_url) return Logger.log_more_verbose("Bruteforcing URL: %s" % m_url) # # Load wordlist for changing directories # # COMMON m_urls = make_url_changing_folder_name(m_url_parts) # Generates the error page m_error_response = get_error_page(m_url) # Create the matching analyzer try: m_store_info = MatchingAnalyzer(m_error_response.raw_data, min_ratio=0.65) except ValueError, e: Logger.log_error("There is not information for analyze when creating the matcher: '%s'" % e) return
def __detect_wordpress_installation(self, url, wordpress_urls): """ Try to detect a wordpress instalation in the current path. :param url: URL where try to find the WordPress installation. :type url: str :param wordpress_urls: string with wordlist name with WordPress URLs. :type wordpress_urls: str :return: True if wordpress installation found. False otherwise. :rtype: bool """ Logger.log_more_verbose( "Detecting Wordpress instalation in URI: '%s'." % url) total_urls = 0 urls_found = 0 error_page = get_error_page(url).raw_data for u in WordListLoader.get_wordlist(wordpress_urls): total_urls += 1 tmp_url = urljoin(url, u) r = HTTP.get_url(tmp_url, use_cache=False) if r.status == "200": # Try to detect non-default error pages ratio = get_diff_ratio(r.raw_response, error_page) if ratio < 0.35: urls_found += 1 discard_data(r) # If Oks > 85% continue if (urls_found / float(total_urls)) < 0.85: # If all fails, make another last test url_wp_admin = urljoin(url, "wp-admin/") try: p = HTTP.get_url(url_wp_admin, use_cache=False, allow_redirects=False) if p: discard_data(p) except Exception, e: return False if p.status == "302" and "wp-login.php?redirect_to=" in p.headers.get( "Location", ""): return True else: return False
def __detect_wordpress_installation(self, url, wordpress_urls): """ Try to detect a wordpress instalation in the current path. :param url: URL where try to find the WordPress installation. :type url: str :param wordpress_urls: string with wordlist name with WordPress URLs. :type wordpress_urls: str :return: True if wordpress installation found. False otherwise. :rtype: bool """ Logger.log_more_verbose("Detecting Wordpress instalation in URI: '%s'." % url) total_urls = 0 urls_found = 0 error_page = get_error_page(url).raw_data for u in WordListLoader.get_wordlist(wordpress_urls): total_urls += 1 tmp_url = urljoin(url, u) r = HTTP.get_url(tmp_url, use_cache=False) if r.status == "200": # Try to detect non-default error pages ratio = get_diff_ratio(r.raw_response, error_page) if ratio < 0.35: urls_found += 1 discard_data(r) # If Oks > 85% continue if (urls_found / float(total_urls)) < 0.85: # If all fails, make another last test url_wp_admin = urljoin(url, "wp-admin/") try: p = HTTP.get_url(url_wp_admin, use_cache=False, allow_redirects=False) if p: discard_data(p) except Exception, e: return False if p.status == "302" and "wp-login.php?redirect_to=" in p.headers.get("Location", ""): return True else: return False
for l_wo in l_loaded_wordlist: try: l_wo = l_wo[1:] if l_wo.startswith("/") else l_wo tmp_u = urljoin(m_url, l_wo) except ValueError, e: Logger.log_error( "Failed to parse key, from wordlist, '%s'" % tmp_u) continue m_urls_update(tmp_u) Logger.log_verbose("Loaded %s URLs to test." % len(urls)) # Generates the error page error_response = get_error_page(m_url) # Create the matching analyzer try: store_info = MatchingAnalyzer(error_response.raw_data, min_ratio=0.65) except ValueError, e: Logger.log_error( "There is not information for analyze when creating the matcher: '%s'" % e) return # Create the partial funs _f = partial(process_url, severity_vectors['predictables'], get_http_method(m_url), store_info, self.update_status, len(urls))
def __find_plugins(self, url, plugins_wordlist, update_func): """ Try to find available plugins :param url: base URL to test. :type url: str :param plugins_wordlist: path to wordlist with plugins lists. :type plugins_wordlist: str :param update_func: function to update plugin status. :type update_func: function :return: list of lists as format: list([PLUGIN_NAME, PLUGIN_URL, PLUGIN_INSTALLED_VERSION, PLUGIN_LAST_VERSION, [CVE1, CVE2...]]) :type: list(list()) """ results = [] urls_to_test = { "readme.txt": r"(Stable tag:[\svV]*)([0-9\.]+)", "README.txt": r"(Stable tag:[\svV]*)([0-9\.]+)", } # Generates the error page error_response = get_error_page(url).raw_data # Load plugins info plugins = [] plugins_append = plugins.append with open(plugins_wordlist, "rU") as f: for x in f: plugins_append(x.replace("\n", "")) # Calculate sizes total_plugins = len(plugins) # Load CSV info csv_info = csv.reader(plugins) # Process the URLs for i, plugin_row in enumerate(csv_info): # Plugin properties plugin_URI = plugin_row[0] plugin_name = plugin_row[1] plugin_last_version = plugin_row[2] plugin_CVEs = [] if plugin_row[3] == "" else plugin_row[3].split("|") # Update status update_func((float(i) * 100.0) / float(total_plugins)) # Make plugin URL partial_plugin_url = "%s/%s" % (url, "wp-content/plugins/%s" % plugin_URI) # Test each URL with possible plugin version info for target, regex in urls_to_test.iteritems(): plugin_url = "%s/%s" % (partial_plugin_url, target) # Try to get plugin p = None try: p = HTTP.get_url(plugin_url, use_cache=False) if p: discard_data(p) except Exception, e: Logger.log_error_more_verbose("Error while download: '%s': %s" % (plugin_url, str(e))) continue plugin_installed_version = None if p.status == "403": # Installed, but inaccesible plugin_installed_version = "Unknown" elif p.status == "200": # Check if page is and non-generic not found page with 404 code if get_diff_ratio(error_response, p.raw_response) < 0.52: # Find the version tmp_version = re.search(regex, p.raw_response) if tmp_version is not None: plugin_installed_version = tmp_version.group(2) # Store info if plugin_installed_version is not None: Logger.log("Discovered plugin: '%s (installed version: %s)' (latest version: %s)" % (plugin_name, plugin_installed_version, plugin_last_version)) results.append([ plugin_name, plugin_url, plugin_installed_version, plugin_last_version, plugin_CVEs ]) # Plugin found -> not more URL test for this plugin break
l_loaded_wordlist = WordListLoader.get_wordlist_as_list(l_w) for l_wo in l_loaded_wordlist: try: l_wo = l_wo[1:] if l_wo.startswith("/") else l_wo tmp_u = urljoin(m_url, l_wo) except ValueError, e: Logger.log_error("Failed to parse key, from wordlist, '%s'" % tmp_u) continue urls.add(tmp_u) Logger.log_verbose("Loaded %s URLs to test." % len(urls)) # Generates the error page error_response = get_error_page(m_url) # Create the matching analyzer try: store_info = MatchingAnalyzer(error_response.raw_data, min_ratio=0.0) except ValueError, e: Logger.log_error("There is not information for analyze when creating the matcher: '%s'" % e) return # Create the partial funs _f = partial(process_url, 4, get_http_method(m_url), store_info, self.update_status, len(urls))
def __find_plugins(self, url, plugins_wordlist, update_func): """ Try to find available plugins :param url: base URL to test. :type url: str :param plugins_wordlist: path to wordlist with plugins lists. :type plugins_wordlist: str :param update_func: function to update plugin status. :type update_func: function :return: list of lists as format: list([PLUGIN_NAME, PLUGIN_URL, PLUGIN_INSTALLED_VERSION, PLUGIN_LAST_VERSION, [CVE1, CVE2...]]) :type: list(list()) """ results = [] urls_to_test = { "readme.txt": r"(Stable tag:[\svV]*)([0-9\.]+)", "README.txt": r"(Stable tag:[\svV]*)([0-9\.]+)", } # Generates the error page error_response = get_error_page(url).raw_data # Load plugins info plugins = [] plugins_append = plugins.append with open(plugins_wordlist, "rU") as f: for x in f: plugins_append(x.replace("\n", "")) # Calculate sizes total_plugins = len(plugins) # Load CSV info csv_info = csv.reader(plugins) # Process the URLs for i, plugin_row in enumerate(csv_info): # Plugin properties plugin_URI = plugin_row[0] plugin_name = plugin_row[1] plugin_last_version = plugin_row[2] plugin_CVEs = [] if plugin_row[3] == "" else plugin_row[3].split( "|") # Update status update_func((float(i) * 100.0) / float(total_plugins)) # Make plugin URL partial_plugin_url = "%s/%s" % (url, "wp-content/plugins/%s" % plugin_URI) # Test each URL with possible plugin version info for target, regex in urls_to_test.iteritems(): plugin_url = "%s/%s" % (partial_plugin_url, target) # Try to get plugin p = None try: p = HTTP.get_url(plugin_url, use_cache=False) if p: discard_data(p) except Exception, e: Logger.log_error_more_verbose( "Error while download: '%s': %s" % (plugin_url, str(e))) continue plugin_installed_version = None if p.status == "403": # Installed, but inaccesible plugin_installed_version = "Unknown" elif p.status == "200": # Check if page is and non-generic not found page with 404 code if get_diff_ratio(error_response, p.raw_response) < 0.52: # Find the version tmp_version = re.search(regex, p.raw_response) if tmp_version is not None: plugin_installed_version = tmp_version.group(2) # Store info if plugin_installed_version is not None: Logger.log( "Discovered plugin: '%s (installed version: %s)' (latest version: %s)" % (plugin_name, plugin_installed_version, plugin_last_version)) results.append([ plugin_name, plugin_url, plugin_installed_version, plugin_last_version, plugin_CVEs ]) # Plugin found -> not more URL test for this plugin break