diff --git a/engine/brute.py b/engine/brute.py index 5ddd7de..2f6a4c9 100644 --- a/engine/brute.py +++ b/engine/brute.py @@ -6,9 +6,9 @@ import os import urllib -from core import * -from wordpress import * -from thread_engine import ThreadEngine +from engine.core import * +from engine.wordpress import * +from engine.thread_engine import ThreadEngine class Brute_Engine: def __init__(self, wordpress, brute, usernames, users_list, passwords_list): @@ -39,7 +39,7 @@ def __init__(self, wordpress, brute, usernames, users_list, passwords_list): print(notice("Bruteforcing detected users: ")) for user in wordpress.users: - print info("User found "+ user['slug']) + print(info("User found "+ user['slug'])) self.bruteforcing_pass(wordpress, user['slug'], passwords_list) diff --git a/engine/core.py b/engine/core.py index 7f692c1..a0c7f02 100644 --- a/engine/core.py +++ b/engine/core.py @@ -62,14 +62,14 @@ def unzip_file(filename): warning : user-agents.txt and timthumbs.txt are zip files """ def database_update(): - print "\033[93mUpdating database\033[92m - Last update: \033[0m" + database_last_date('database/local_vulnerable_files.xml') + print("\033[93mUpdating database\033[92m - Last update: \033[0m" + database_last_date('database/local_vulnerable_files.xml')) update_url = "https://data.wpscan.org/" update_files = [ 'local_vulnerable_files.xml', 'local_vulnerable_files.xsd', 'timthumbs.txt', 'user-agents.txt', 'wp_versions.xml', 'wp_versions.xsd', 'wordpresses.json', 'plugins.json', 'themes.json'] for f in update_files: - print "\t\033[93mDownloading \033[0m"+ f +" \033[92mFile updated !\033[0m" + print("\t\033[93mDownloading \033[0m"+ f +" \033[92mFile updated !\033[0m") download_raw_file(update_url+f, "database/"+f, True) unzip_file("database/user-agents.txt") @@ -214,26 +214,26 @@ def display_vulnerable_component(name, version, file): with open('database/' + file + '.json') as data_file: data = json.load(data_file) - print warning("Name: %s - v%s" % (name, version)) + print(warning("Name: %s - v%s" % (name, version))) if name in data.keys(): # Display the out of date info if the version is lower of the latest version if is_lower(version, data[name]['latest_version'], False): - print info("The version is out of date, the latest version is %s" % data[name]['latest_version']) + print(info("The version is out of date, the latest version is %s" % data[name]['latest_version'])) # Display the vulnerability if it's not patched version for vuln in data[name]['vulnerabilities']: if 'fixed_in' in vuln.keys() and (vuln['fixed_in'] == None or is_lower(version, vuln['fixed_in'], True)): # Main informations - print "\t",vulnerable("%s : %s - ID:%s" % (vuln['vuln_type'], vuln['title'] , vuln['id']) ) - print "\t",display("Fixed in %s"% vuln['fixed_in']) + print("\t",vulnerable("%s : %s - ID:%s" % (vuln['vuln_type'], vuln['title'] , vuln['id']) )) + print("\t",display("Fixed in %s"% vuln['fixed_in'])) # Display references - print "\t",display("References:") + print("\t",display("References:")) for refkey in vuln['references'].keys(): for ref in vuln['references'][refkey]: if refkey != 'url': - print "\t\t - %s %s" % (refkey.capitalize(), ref) + print("\t\t - %s %s" % (refkey.capitalize(), ref)) else: - print "\t\t - %s" %ref + print("\t\t - %s" % ref) diff --git a/engine/fuzz.py b/engine/fuzz.py index 5b1fca7..c3d0b40 100644 --- a/engine/fuzz.py +++ b/engine/fuzz.py @@ -5,8 +5,8 @@ import json from tornado import ioloop, httpclient -from core import * -from wordpress import * +from engine.core import * +from engine.wordpress import * from lxml import etree from multiprocessing import Process, Pool @@ -22,7 +22,7 @@ def __init__(self, wordpress, fuzz): description : fuzz every component used by the wordpress """ def fuzzing_component_aggressive(self, wordpress): - print notice("Enumerating components from aggressive fuzzing ...") + print(notice("Enumerating components from aggressive fuzzing ...")) # Load json file with open('fuzz/wordpress.fuzz') as data_file: @@ -45,7 +45,7 @@ def fuzzing_component_aggressive(self, wordpress): description : fuzz every themes used by the wordpress """ def fuzzing_themes_aggressive(self, wordpress): - print notice("Enumerating themes from aggressive fuzzing ...") + print(notice("Enumerating themes from aggressive fuzzing ...")) # Load json file with open('fuzz/wp_themes.fuzz') as data_file: @@ -68,7 +68,7 @@ def fuzzing_themes_aggressive(self, wordpress): description : fuzz every plugins used by the wordpress """ def fuzzing_plugins_aggressive(self, wordpress): - print notice("Enumerating plugins from aggressive fuzzing ...") + print(notice("Enumerating plugins from aggressive fuzzing ...")) # Load json file with open('fuzz/wp_plugins.fuzz') as data_file: @@ -106,9 +106,9 @@ def aggressive_request_themes(response): def aggressive_request_component(response): if (response.code) == 200: if "reauth" in response.effective_url: - print "[i] Authentication Needed: " + response.effective_url+ " - found" + print("[i] Authentication Needed: " + response.effective_url+ " - found") else: - print "[i] File: " + response.effective_url+ " - found" + print("[i] File: " + response.effective_url+ " - found") global iter_aggressive iter_aggressive-= 1 diff --git a/engine/load_plugins.py b/engine/load_plugins.py index e36749a..385e049 100644 --- a/engine/load_plugins.py +++ b/engine/load_plugins.py @@ -6,7 +6,7 @@ import os import imp -from wordpress import * +from engine.wordpress import * class Load_Plugins: plugin_folder = "./plugins" @@ -14,7 +14,7 @@ class Load_Plugins: def __init__(self, wordpress): available_plugins = os.listdir(self.plugin_folder) for plugins in available_plugins: - if not ".pyc" in plugins and not "__init__" in plugins: + if not ".pyc" in plugins and not "__init__" in plugins and not "__pycache__" in plugins: # Find and load the package name = plugins.replace('.py','') @@ -26,5 +26,5 @@ def __init__(self, wordpress): loaded = imp.load_module('plugins.' + name, f, file, desc) # Run the __init__ - print notice('Plugin %s loaded.' % loaded.name) + print(notice('Plugin %s loaded.' % loaded.name)) loaded.__init__(wordpress) diff --git a/engine/scan.py b/engine/scan.py index d25608a..a9ffb9c 100644 --- a/engine/scan.py +++ b/engine/scan.py @@ -5,8 +5,8 @@ import json from tornado import ioloop, httpclient -from core import * -from wordpress import * +from engine.core import * +from engine.wordpress import * from lxml import etree from multiprocessing import Process, Pool @@ -30,7 +30,7 @@ def fingerprint_wp_version_meta_based(self, wordpress): match = regex.findall(wordpress.index.text) if match != []: wordpress.version = match[0] - print critical("WordPress version %s identified from advanced fingerprinting" % wordpress.version) + print(critical("WordPress version %s identified from advanced fingerprinting" % wordpress.version)) return True return False @@ -45,7 +45,7 @@ def fingerprint_wp_version_feed_based(self, wordpress): match = regex.findall(r) if match != []: wordpress.version = match[0] - print critical("WordPress version %s identified from advanced fingerprinting" % wordpress.version) + print(critical("WordPress version %s identified from advanced fingerprinting" % wordpress.version)) return True return False @@ -79,7 +79,7 @@ def fingerprint_wp_version_hash_based(self, wordpress): # Detect the version if ddl_hash == root[i][j].get('md5'): wordpress.version = root[i][j][0].text - print critical("WordPress version %s identified from advanced fingerprinting" % wordpress.version) + print(critical("WordPress version %s identified from advanced fingerprinting" % wordpress.version)) return @@ -110,7 +110,7 @@ def list_wp_version_vulnerabilities(self, wordpress, file): # This version doesn't exist if wordpress.version not in data: - print warning("The version %s isn't in the database - Please try the option --update" % (wordpress.version)) + print(warning("The version %s isn't in the database - Please try the option --update" % (wordpress.version))) return if data[wordpress.version]["vulnerabilities"] == []: @@ -124,20 +124,20 @@ def list_wp_version_vulnerabilities(self, wordpress, file): for vuln in data[version]["vulnerabilities"]: # Basic infos - print warning("\t%s : %s - ID:%s" % (vuln['vuln_type'], vuln['title'] , vuln['id']) ) - print info("\tFixed in %s"% vuln['fixed_in']) + print(warning("\t%s : %s - ID:%s" % (vuln['vuln_type'], vuln['title'] , vuln['id']))) + print(info("\tFixed in %s"% vuln['fixed_in'])) # Display references - print info("\tReferences:") + print(info("\tReferences:")) for refkey in vuln['references'].keys(): for ref in vuln['references'][refkey]: if refkey != 'url': - print "\t\t - %s %s" % (refkey.capitalize(), ref) + print("\t\t - %s %s" % (refkey.capitalize(), ref)) else: - print "\t\t - %s" %ref + print("\t\t - %s" % ref) - print "" + print("") """ @@ -145,7 +145,7 @@ def list_wp_version_vulnerabilities(self, wordpress, file): description : enumerate every theme used by the wordpress """ def enumerating_themes_passive(self, wordpress): - print notice("Enumerating themes from passive detection ...") + print(notice("Enumerating themes from passive detection ...")) # Theme name (css file) regex = re.compile('wp-content/themes/(.*?)/.*?[css|js].*?ver=([0-9\.]*)') @@ -173,7 +173,7 @@ def enumerating_themes_passive(self, wordpress): description : enumerate every plugins used by the wordpress """ def enumerating_plugins_passive(self, wordpress): - print notice("Enumerating plugins from passive detection ...") + print(notice("Enumerating plugins from passive detection ...")) # Plugin name (js file) regex = re.compile('wp-content/plugins/(.*?)/.*?[css|js].*?ver=([0-9\.]*)') @@ -201,7 +201,7 @@ def enumerating_plugins_passive(self, wordpress): description : enumerate every themes used by the wordpress """ def enumerating_themes_aggressive(self, wordpress): - print notice("Enumerating themes from aggressive detection ...") + print(notice("Enumerating themes from aggressive detection ...")) # Load json file with open('database/themes.json') as data_file: @@ -222,7 +222,7 @@ def enumerating_themes_aggressive(self, wordpress): description : enumerate every plugins used by the wordpress """ def enumerating_plugins_aggressive(self, wordpress): - print notice("Enumerating plugins from aggressive detection ...") + print(notice("Enumerating plugins from aggressive detection ...")) # Load json file with open('database/plugins.json') as data_file: diff --git a/engine/thread_engine.py b/engine/thread_engine.py index ff31d1e..a8e112a 100644 --- a/engine/thread_engine.py +++ b/engine/thread_engine.py @@ -2,17 +2,17 @@ # -*- coding: utf-8 -*- from threading import Thread # from time import sleep -from core import critical, info +from engine.core import critical, info class ThreadEngine(object): def __init__(self, max_threads): if max_threads < 1: - print critical('Threads number must be > 0') + print(critical('Threads number must be > 0')) exit() self.max_threads = max_threads self.threads = [] - print info('Start %d threads ...' % self.max_threads) + print(info('Start %d threads ...' % self.max_threads)) def new_task(self, task, args): """ Try to launch the new task, @@ -38,9 +38,9 @@ def launch_task(self, task, args): def clean_threads(self): """ Remove ended threads """ - for thread in self.threads: - if not thread.isAlive(): - self.threads.remove(thread) + for thread in self.threads: + if not thread.isAlive(): + self.threads.remove(thread) def wait(self): """ Wait for threads end """ diff --git a/engine/wordpress.py b/engine/wordpress.py index acf4942..8edb8a6 100644 --- a/engine/wordpress.py +++ b/engine/wordpress.py @@ -4,7 +4,7 @@ import re import json from random import randint -from core import * +from engine.core import * class Wordpress: url = "http://wp-example.com" @@ -17,7 +17,7 @@ class Wordpress: files = set() def __init__(self, url, user_agent, nocheck, max_threads): - print info("URL: %s" % url) + print(info("URL: %s" % url)) self.url = url self.agent = user_agent self.max_threads = int(max_threads) @@ -71,7 +71,7 @@ def is_wordpress(self, nocheck): self.index = requests.get(self.url, headers={"User-Agent":self.agent}, verify=False) if nocheck == False: if not "wp-" in self.index.text: - print critical("Not a WordPress !") + print(critical("Not a WordPress !")) exit() """ @@ -81,29 +81,24 @@ def is_wordpress(self, nocheck): def is_up_and_installed(self): try: r = requests.get(self.url, allow_redirects=False, headers={"User-Agent":self.agent} , verify=False) - - if 'location' in r.headers: - - # Install is not complete + if 'location' in r.headers: + # Install is not complete if "wp-admin/install.php" in r.headers['location']: - print critical("The Website is not fully configured and currently in install mode. Call it to create a new admin user.") - exit() - - # Redirect - print notice("The remote host tried to redirect to: %s" % r.headers['location']) - user_input = str(raw_input("[?] Do you want to follow the redirection ? [Y]es [N]o, ")) - - if user_input.lower() == "y": - self.url = r.headers['location'] - - else: - print critical("Redirection not followed - End of the scan !") - exit() + print(critical("The Website is not fully configured and currently in install mode. Call it to create a new admin user.")) + exit() + # Redirect + print(notice("The remote host tried to redirect to: %s" % r.headers['location'])) + user_input = str(raw_input("[?] Do you want to follow the redirection ? [Y]es [N]o, ")) + if user_input.lower() == "y": + self.url = r.headers['location'] + else: + print(critical("Redirection not followed - End of the scan !")) + exit() except Exception as e: - print e - print critical("Website down!") - exit() + print(e) + print(critical("Website down!")) + exit() """ @@ -123,7 +118,7 @@ def is_readme(self): if len(matches) > 0 and matches[0] != None and matches[0] != "": self.version = matches[0] - print critical("The Wordpress '%s' file exposing a version number: %s" % (self.url+'readme.html', matches[0])) + print(critical("The Wordpress '%s' file exposing a version number: %s" % (self.url+'readme.html', matches[0]))) """ name : is_debug_log() @@ -133,7 +128,7 @@ def is_debug_log(self): r = requests.get(self.url + 'debug.log', headers={"User-Agent":self.agent}, verify=False) if "200" in str(r) and not "404" in r.text : self.files.add('debug.log') - print critical( "Debug log file found: %s" % (self.url + 'debug.log') ) + print(critical( "Debug log file found: %s" % (self.url + 'debug.log'))) """ @@ -176,7 +171,7 @@ def is_backup_file(self): r = requests.get(self.url + b, headers={"User-Agent":self.agent}, verify=False) if "200" in str(r) and not "404" in r.text : self.files.add(b) - print critical("A wp-config.php backup file has been found in: %s" % (self.url + b) ) + print(critical("A wp-config.php backup file has been found in: %s" % (self.url + b))) """ @@ -187,7 +182,7 @@ def is_xml_rpc(self): r = requests.get(self.url + "xmlrpc.php", headers={"User-Agent":self.agent}, verify=False) if r.status_code == 405 : self.files.add("xmlrpc.php") - print info("XML-RPC Interface available under: %s " % (self.url+"xmlrpc.php") ) + print(info("XML-RPC Interface available under: %s " % (self.url+"xmlrpc.php"))) """ @@ -202,7 +197,7 @@ def is_directory_listing(self): r = requests.get(self.url + directory, headers={"User-Agent":self.agent}, verify=False) if "Index of" in r.text: self.files.add(directory) - print warning("%s directory has directory listing enabled : %s" % (name, self.url + directory)) + print(warning("%s directory has directory listing enabled : %s" % (name, self.url + directory))) """ @@ -213,11 +208,11 @@ def is_robots_text(self): r = requests.get(self.url + "robots.txt", headers={"User-Agent":self.agent}, verify=False) if "200" in str(r) and not "404" in r.text : self.files.add("robots.txt") - print info("robots.txt available under: %s " % (self.url+"robots.txt") ) + print(info("robots.txt available under: %s " % (self.url+"robots.txt"))) lines = r.text.split('\n') for l in lines: if "Disallow:" in l: - print info("\tInteresting entry from robots.txt: %s" % (l)) + print(info("\tInteresting entry from robots.txt: %s" % (l))) """ name : is_common_file() @@ -229,7 +224,7 @@ def is_common_file(self): r = requests.get(self.url + f, headers={"User-Agent":self.agent}, verify=False) if "200" in str(r) and not "404" in r.text : self.files.add(f) - print info("%s available under: %s " % (f, self.url+f) ) + print(info("%s available under: %s " % (f, self.url+f))) """ name : full_path_disclosure() @@ -241,7 +236,7 @@ def full_path_disclosure(self): matches = regex.findall(r) if matches != []: - print warning("Full Path Disclosure (FPD) in %s exposing %s" % (self.url + "wp-includes/rss-functions.php", matches[0].replace('\n','')) ) + print(warning("Full Path Disclosure (FPD) in %s exposing %s" % (self.url + "wp-includes/rss-functions.php", matches[0].replace('\n','')))) """ @@ -252,10 +247,10 @@ def enum_wordpress_users(self): r = requests.get(self.url + "wp-json/wp/v2/users", headers={"User-Agent":self.agent} , verify=False) if "200" in str(r): - print notice("Enumerating Wordpress users") + print(notice("Enumerating Wordpress users")) users = json.loads(r.text) for user in users: - print info("\tIdentified the following user : %s, %s, %s" % (user['id'], user['name'], user['slug']) ) + print(info("\tIdentified the following user : %s, %s, %s" % (user['id'], user['name'], user['slug']))) self.users = users @@ -264,12 +259,12 @@ def enum_wordpress_users(self): description : display a debug view of the object """ def to_string(self): - print "--------WORDPRESS----------" - print "URL : %s" % self.url - print "Version : %s" % self.version - print "Plugins : %s" % self.plugins - print "Themes : %s" % self.themes - print "Agent : %s" % self.agent - print "Users : %s" % self.users - print "Files : %s" % self.files - print "---------------------------" + print("--------WORDPRESS----------") + print("URL : %s" % self.url) + print("Version : %s" % self.version) + print("Plugins : %s" % self.plugins) + print("Themes : %s" % self.themes) + print("Agent : %s" % self.agent) + print("Users : %s" % self.users) + print("Files : %s" % self.files) + print("---------------------------") diff --git a/plugins/_thank-you.py b/plugins/_thank-you.py index a24da62..28ea6b8 100644 --- a/plugins/_thank-you.py +++ b/plugins/_thank-you.py @@ -11,5 +11,5 @@ def __init__(wordpress): # INSERT CODE HERE! - print "Thank you for using this software :)" + print("Thank you for using this software :)") return diff --git a/plugins/git-files.py b/plugins/git-files.py index 5fdb2d1..14d2231 100644 --- a/plugins/git-files.py +++ b/plugins/git-files.py @@ -14,5 +14,5 @@ def __init__(wordpress): r = requests.get(wordpress.url + payload, headers={"User-Agent":wordpress.agent}, verify=False) if "200" in str(r): - print "[+] Wordpress configuration found from GIT !" - print "[!] {}".format(wordpress.url + payload) + print("[+] Wordpress configuration found from GIT !") + print("[!] {}".format(wordpress.url + payload)) diff --git a/plugins/svn-files.py b/plugins/svn-files.py index 2e3e682..8e47bca 100644 --- a/plugins/svn-files.py +++ b/plugins/svn-files.py @@ -14,5 +14,5 @@ def __init__(wordpress): r = requests.get(wordpress.url + payload, headers={"User-Agent":wordpress.agent}, verify=False) if "200" in str(r): - print "[+] Wordpress configuration found from SVN !" - print "[!] {}".format(wordpress.url + payload) + print("[+] Wordpress configuration found from SVN !") + print("[!] {}".format(wordpress.url + payload)) diff --git a/wordpresscan.py b/wordpresscan.py index 65f4ce9..94d0147 100644 --- a/wordpresscan.py +++ b/wordpresscan.py @@ -12,17 +12,17 @@ if __name__ == "__main__": - print "_______________________________________________________________ " - print " _ _ _ " - print "| | | | | | " - print "| | | | ___ _ __ __| |_ __ _ __ ___ ___ ___ ___ __ _ _ __ " - print "| |/\| |/ _ \| '__/ _` | '_ \| '__/ _ \/ __/ __|/ __/ _` | '_ \ " - print "\ /\ / (_) | | | (_| | |_) | | | __/\__ \__ \ (_| (_| | | | |" - print " \/ \/ \___/|_| \__,_| .__/|_| \___||___/___/\___\__,_|_| |_|" - print " | | " - print " |_| " - print " WordPress scanner based on wpscan work - @pentest_swissky " - print "_______________________________________________________________ " + print("_______________________________________________________________ ") + print(" _ _ _ ") + print("| | | | | | ") + print("| | | | ___ _ __ __| |_ __ _ __ ___ ___ ___ ___ __ _ _ __ ") + print("| |/\| |/ _ \| '__/ _` | '_ \| '__/ _ \/ __/ __|/ __/ _` | '_ \ ") + print("\ /\ / (_) | | | (_| | |_) | | | __/\__ \__ \ (_| (_| | | | |") + print(" \/ \/ \___/|_| \__,_| .__/|_| \___||___/___/\___\__,_|_| |_|") + print(" | | ") + print(" |_| ") + print(" WordPress scanner based on wpscan work - @pentest_swissky ") + print("_______________________________________________________________ ") parser = argparse.ArgumentParser() parser.add_argument('-u', action ='store', dest='url', help="Wordpress URL")