diff --git a/bin/unzip_gecko.py b/bin/unzip_gecko.py index 649d2d9..132f4f7 100644 --- a/bin/unzip_gecko.py +++ b/bin/unzip_gecko.py @@ -1,11 +1,11 @@ import os import platform -import tarfile import subprocess +import tarfile import whichcraft -import lib.settings +import lib.core.settings def disclaimer(): @@ -21,7 +21,7 @@ def disclaimer(): if question.upper() == "YES": return True else: - lib.settings.logger.fatal(lib.settings.set_color( + lib.core.settings.logger.fatal(lib.core.settings.set_color( "you have not agreed with the terms of service, so " "Zeus will shut down now...", level=50 )) @@ -42,7 +42,7 @@ def check_xvfb(exc="Xvfb"): test for xvfb on the users system """ if whichcraft.which(exc) is None: - lib.settings.logger.info(lib.settings.set_color( + lib.core.settings.logger.info(lib.core.settings.set_color( "installing Xvfb, required by pyvirutaldisplay..." )) subprocess.call(["sudo", "apt-get", "install", "xvfb"]) @@ -73,30 +73,30 @@ def untar_gecko(filename="{}/bin/geckodriver-v0.18.0-linux{}.tar.gz", verbose=Fa file_arch = arch_info[platform.architecture()[0]] tar = tarfile.open(filename.format(os.getcwd(), file_arch), "r:gz") if verbose: - lib.settings.logger.debug(lib.settings.set_color( + lib.core.settings.logger.debug(lib.core.settings.set_color( "extracting the correct driver for your architecture...", level=10 )) try: tar.extractall("/usr/bin") if verbose: - lib.settings.logger.debug(lib.settings.set_color( + lib.core.settings.logger.debug(lib.core.settings.set_color( "driver extracted into /usr/bin (you may change this, but ensure that it " "is in your PATH)...", level=10 )) except IOError as e: if "Text file busy" in str(e): - lib.settings.logger.info(lib.settings.set_color( + lib.core.settings.logger.info(lib.core.settings.set_color( "the driver is already installed..." )) tar.close() pass except Exception as e: if "[Errno 13] Permission denied: '/usr/bin/geckodriver'" in str(e): - lib.settings.logger.exception(lib.settings.set_color( + lib.core.settings.logger.exception(lib.core.settings.set_color( "first run must be ran as root (sudo python zeus.py)...", level=50 )) else: - lib.settings.logger.exception(lib.settings.set_color( + lib.core.settings.logger.exception(lib.core.settings.set_color( "ran into exception '{}', logged to current log file...".format(e), level=50 )) exit(-1) @@ -108,11 +108,11 @@ def ensure_placed(item="geckodriver", verbose=False): use whichcraft to ensure that the driver has been placed in your PATH variable """ if verbose: - lib.settings.logger.debug(lib.settings.set_color( + lib.core.settings.logger.debug(lib.core.settings.set_color( "ensuring that the driver exists in your system path...", level=10 )) if not whichcraft.which(item): - lib.settings.logger.fatal(lib.settings.set_color( + lib.core.settings.logger.fatal(lib.core.settings.set_color( "the executable '{}' does not appear to be in your /usr/bin PATH. " "please untar the correct geckodriver (if not already done) and move " "it to /usr/bin.".format(item), level=50 @@ -120,7 +120,7 @@ def ensure_placed(item="geckodriver", verbose=False): exit(-1) else: if verbose: - lib.settings.logger.debug(lib.settings.set_color( + lib.core.settings.logger.debug(lib.core.settings.set_color( "driver exists, continuing...", level=10 )) return True @@ -131,11 +131,11 @@ def main(rewrite="{}/bin/executed.txt", verbose=False): main method """ if verbose: - lib.settings.logger.debug(lib.settings.set_color( + lib.core.settings.logger.debug(lib.core.settings.set_color( "verifying operating system...", level=10 )) if not check_os(): - raise NotImplementedError(lib.settings.set_color( + raise NotImplementedError(lib.core.settings.set_color( "as of now, Zeus requires Linux to run successfully " "your current operating system '{}' is not implemented " "yet...".format(platform.platform()), level=50 @@ -143,12 +143,12 @@ def main(rewrite="{}/bin/executed.txt", verbose=False): if check_if_run(): if not disclaimer(): exit(1) - lib.settings.logger.info(lib.settings.set_color( + lib.core.settings.logger.info(lib.core.settings.set_color( "seems this is your first time running the appication, " "doing setup please wait..." )) if verbose: - lib.settings.logger.debug(lib.settings.set_color( + lib.core.settings.logger.debug(lib.core.settings.set_color( "checking if xvfb is on your system...", level=10 )) check_xvfb() @@ -156,11 +156,11 @@ def main(rewrite="{}/bin/executed.txt", verbose=False): if ensure_placed(verbose=verbose): with open(rewrite.format(os.getcwd()), "w") as rw: rw.write("TRUE") - lib.settings.logger.info(lib.settings.set_color( + lib.core.settings.logger.info(lib.core.settings.set_color( "done, continuing process..." )) else: if verbose: - lib.settings.logger.debug(lib.settings.set_color( + lib.core.settings.logger.debug(lib.core.settings.set_color( "already ran, skipping...", level=10 )) diff --git a/lib/attacks/admin_panel_finder/__init__.py b/lib/attacks/admin_panel_finder/__init__.py index 0264850..480113a 100644 --- a/lib/attacks/admin_panel_finder/__init__.py +++ b/lib/attacks/admin_panel_finder/__init__.py @@ -7,7 +7,7 @@ except ImportError: # Python 3 from urllib2 import urlopen, HTTPError from var.auto_issue.github import request_issue_creation -from lib.settings import ( +from lib.core.settings import ( logger, replace_http, set_color, diff --git a/lib/attacks/intel_me/__init__.py b/lib/attacks/intel_me/__init__.py index 66c319d..72947d7 100644 --- a/lib/attacks/intel_me/__init__.py +++ b/lib/attacks/intel_me/__init__.py @@ -1,15 +1,15 @@ -import re import json +import re import requests from lxml import html -from var.auto_issue.github import request_issue_creation -from lib.settings import ( +from lib.core.settings import ( proxy_string_to_dict, logger, set_color, DEFAULT_USER_AGENT, ) +from var.auto_issue.github import request_issue_creation def __get_auth_headers(target, port=16992, source=None, agent=None, proxy=None): diff --git a/lib/attacks/nmap_scan/__init__.py b/lib/attacks/nmap_scan/__init__.py index 2aa40d1..c67d539 100644 --- a/lib/attacks/nmap_scan/__init__.py +++ b/lib/attacks/nmap_scan/__init__.py @@ -1,15 +1,16 @@ -import os -import nmap import json +import os import socket -from var.auto_issue.github import request_issue_creation -from lib.settings import ( +import nmap + +from lib.core.settings import ( logger, set_color, create_dir, find_application, ) +from var.auto_issue.github import request_issue_creation class NmapHook(object): diff --git a/lib/attacks/sqlmap_scan/__init__.py b/lib/attacks/sqlmap_scan/__init__.py index 6539ca9..be07af6 100644 --- a/lib/attacks/sqlmap_scan/__init__.py +++ b/lib/attacks/sqlmap_scan/__init__.py @@ -1,5 +1,6 @@ -import re import json +import re + try: import urllib2 # python 2 except ImportError: @@ -8,8 +9,8 @@ import subprocess import requests -import lib.settings -import lib.errors +import lib.core.settings +import lib.core.errors from var.auto_issue.github import request_issue_creation @@ -53,11 +54,11 @@ class SqlmapHook(object): if len(found) > 16: data_found = [found[i:i+split_by] for i in range(0, len(found), split_by)] for item in data_found: - if item not in lib.settings.ALREADY_USED: - lib.settings.ALREADY_USED.add(item) + if item not in lib.core.settings.ALREADY_USED: + lib.core.settings.ALREADY_USED.add(item) current_scan_id = item else: - lib.settings.ALREADY_USED.add(found) + lib.core.settings.ALREADY_USED.add(found) current_scan_id = found return current_scan_id @@ -84,7 +85,7 @@ class SqlmapHook(object): status_json = json.loads(status_req.content) current_status = status_json["status"] if current_status != "running": - raise lib.errors.SqlmapFailedStart( + raise lib.core.errors.SqlmapFailedStart( "sqlmap API failed to start the run, check the client and see what " "the problem is and try again..." ) @@ -111,7 +112,7 @@ def find_sqlmap(given_search_path=None, to_find="sqlmapapi.py", verbose=False): """ find sqlmap on the users system """ - return lib.settings.find_application(to_find, verbose=verbose, given_search_path=given_search_path) + return lib.core.settings.find_application(to_find, verbose=verbose, given_search_path=given_search_path) def sqlmap_scan_main(url, port=None, verbose=None, auto_search=False, opts=None, given_path=None, full_path=None): @@ -126,7 +127,7 @@ def sqlmap_scan_main(url, port=None, verbose=None, auto_search=False, opts=None, return {key: value for key, value in opts} if auto_search: - lib.settings.logger.info(lib.settings.set_color( + lib.core.settings.logger.info(lib.core.settings.set_color( "attempting to find sqlmap on your system..." )) path = ''.join(find_sqlmap(verbose=verbose, given_search_path=given_path)) @@ -135,39 +136,39 @@ def sqlmap_scan_main(url, port=None, verbose=None, auto_search=False, opts=None, else: try: sqlmap_scan = SqlmapHook(url, port=port) - lib.settings.logger.info(lib.settings.set_color( + lib.core.settings.logger.info(lib.core.settings.set_color( "initializing new sqlmap scan with given URL '{}'...".format(url) )) sqlmap_scan.init_new_scan() if verbose: - lib.settings.logger.debug(lib.settings.set_color( + lib.core.settings.logger.debug(lib.core.settings.set_color( "scan initialized...", level=10 )) - lib.settings.logger.info(lib.settings.set_color( + lib.core.settings.logger.info(lib.core.settings.set_color( "gathering sqlmap API scan ID..." )) api_id = sqlmap_scan.get_scan_id() if verbose: - lib.settings.logger.debug(lib.settings.set_color( + lib.core.settings.logger.debug(lib.core.settings.set_color( "current sqlmap scan ID: '{}'...".format(api_id), level=10 )) - lib.settings.logger.info(lib.settings.set_color( + lib.core.settings.logger.info(lib.core.settings.set_color( "starting sqlmap scan on url: '{}'...".format(url) )) if opts: if verbose: - lib.settings.logger.debug(lib.settings.set_color( + lib.core.settings.logger.debug(lib.core.settings.set_color( "using arguments: '{}'...".format(___dict_args()), level=10 )) - lib.settings.logger.info(lib.settings.set_color( + lib.core.settings.logger.info(lib.core.settings.set_color( "adding arguments to sqlmap API..." )) else: if verbose: - lib.settings.logger.debug(lib.settings.set_color( + lib.core.settings.logger.debug(lib.core.settings.set_color( "no arguments passed, skipping...", level=10 )) - lib.settings.logger.warning(lib.settings.set_color( + lib.core.settings.logger.warning(lib.core.settings.set_color( "please keep in mind that this is the API, output will " "not be saved to log file, it may take a little longer " "to finish processing, launching sqlmap...", level=30 @@ -177,14 +178,14 @@ def sqlmap_scan_main(url, port=None, verbose=None, auto_search=False, opts=None, sqlmap_scan.show_sqlmap_log(api_id) print("-" * 30) except requests.exceptions.HTTPError as e: - lib.settings.logger.exception(lib.settings.set_color( + lib.core.settings.logger.exception(lib.core.settings.set_color( "ran into error '{}', seems you didn't start the server, check " "the server port and try again...".format(e), level=50 )) pass except Exception as e: if "HTTPConnectionPool(host='127.0.0.1'" in str(e): - lib.settings.logger.error(lib.settings.set_color( + lib.core.settings.logger.error(lib.core.settings.set_color( "sqlmap API is not started, did you forget to start it? " "You will need to open a new terminal, cd into sqlmap, and " "run `python sqlmapapi.py -s` otherwise pass the correct flags " @@ -192,7 +193,7 @@ def sqlmap_scan_main(url, port=None, verbose=None, auto_search=False, opts=None, )) pass else: - lib.settings.logger.exception(lib.settings.set_color( + lib.core.settings.logger.exception(lib.core.settings.set_color( "ran into error '{}', seems something went wrong, error has " "been saved to current log file.".format(e), level=50 )) diff --git a/lib/attacks/tamper_scripts/__init__.py b/lib/attacks/tamper_scripts/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/lib/attacks/tamper_scripts/base64_encode.py b/lib/attacks/tamper_scripts/base64_encode.py deleted file mode 100644 index a1a9bde..0000000 --- a/lib/attacks/tamper_scripts/base64_encode.py +++ /dev/null @@ -1,15 +0,0 @@ -import base64 - -from lib.settings import ( - logger, - set_color -) - - -def tamper(payload, warning=True, **kwargs): - if warning: - logger.warning(set_color( - "base64 tamper scripts may increase the possibility of not finding vulnerabilities " - "in otherwise vulnerable sites...", level=30 - )) - return base64.b64encode(payload) \ No newline at end of file diff --git a/lib/attacks/tamper_scripts/hex_encode.py b/lib/attacks/tamper_scripts/hex_encode.py deleted file mode 100644 index b9bee63..0000000 --- a/lib/attacks/tamper_scripts/hex_encode.py +++ /dev/null @@ -1,16 +0,0 @@ -from lib.settings import ( - logger, - set_color -) - - -def tamper(payload, warning=True, **kwargs): - if warning: - logger.warning(set_color( - "hex tamper scripts may increase the risk of false positives...", level=30 - )) - retval = hex(hash(payload)) - if "-" in str(retval): - return retval[1:-1] - else: - return retval diff --git a/lib/attacks/tamper_scripts/lowercase_encode.py b/lib/attacks/tamper_scripts/lowercase_encode.py deleted file mode 100644 index f81573c..0000000 --- a/lib/attacks/tamper_scripts/lowercase_encode.py +++ /dev/null @@ -1,2 +0,0 @@ -def tamper(payload, **kwargs): - return str(payload).lower() \ No newline at end of file diff --git a/lib/attacks/tamper_scripts/randomcase_encode.py b/lib/attacks/tamper_scripts/randomcase_encode.py deleted file mode 100644 index 0a9ffeb..0000000 --- a/lib/attacks/tamper_scripts/randomcase_encode.py +++ /dev/null @@ -1,14 +0,0 @@ -import random - - -def tamper(payload, **kwargs): - retval = "" - nums = [0, 1] - - for char in payload: - random_int = random.choice(nums) - if random_int == 1: - retval += char.upper() - else: - retval += char - return retval diff --git a/lib/attacks/tamper_scripts/unicode_encode.py b/lib/attacks/tamper_scripts/unicode_encode.py deleted file mode 100644 index 1433fa7..0000000 --- a/lib/attacks/tamper_scripts/unicode_encode.py +++ /dev/null @@ -1,8 +0,0 @@ -def tamper(payload, **kwargs): - i = 0 - retval = "" - - while i < len(payload): - retval += "%u{}".format(ord(payload[i])) - i += 1 - return retval diff --git a/lib/attacks/tamper_scripts/uppercase_encode.py b/lib/attacks/tamper_scripts/uppercase_encode.py deleted file mode 100644 index 792cca4..0000000 --- a/lib/attacks/tamper_scripts/uppercase_encode.py +++ /dev/null @@ -1,2 +0,0 @@ -def tamper(payload, **kwargs): - return str(payload).upper() \ No newline at end of file diff --git a/lib/attacks/tamper_scripts/url_encode.py b/lib/attacks/tamper_scripts/url_encode.py deleted file mode 100644 index 32eee14..0000000 --- a/lib/attacks/tamper_scripts/url_encode.py +++ /dev/null @@ -1,45 +0,0 @@ -# coding=utf-8 - - -def tamper(payload, safe="%&=-_", **kwargs): - encodings = { - " ": "%20", "!": "%21", '"': "%22", "#": "%23", "$": "%24", "%": "%25", "&": "%26", "'": "%27", - "(": "%28", ")": "%29", "*": "%2A", "+": "%2B", ",": "%2C", "-": "%2D", ".": "%2E", "/": "%2F", - "0": "%30", "1": "%31", "2": "%32", "3": "%33", "4": "%34", "5": "%35", "6": "%36", "7": "%37", - "8": "%38", "9": "%39", ":": "%3A", ";": "%3B", "<": "%3C", "=": "%3D", ">": "%3E", "?": "%3F", - "@": "%40", "A": "%41", "B": "%42", "C": "%43", "D": "%44", "E": "%45", "F": "%46", "G": "%47", - "H": "%48", "I": "%49", "J": "%4A", "K": "%4B", "L": "%4C", "M": "%4D", "N": "%4E", "O": "%4F", - "P": "%50", "Q": "%51", "R": "%52", "S": "%53", "T": "%54", "U": "%55", "V": "%56", "W": "%57", - "X": "%58", "Y": "%59", "Z": "%5A", "[": "%5B", "\\": "%5C", "]": "%5D", "^": "%5E", "a": "%61", - "b": "%62", "c": "%63", "d": "%64", "e": "%65", "f": "%66", "g": "%67", "h": "%68", "i": "%69", - "j": "%6A", "k": "%6B", "l": "%6C", "m": "%6D", "n": "%6E", "o": "%6F", "p": "%70", "q": "%71", - "r": "%72", "s": "%73", "t": "%74", "u": "%75", "v": "%76", "w": "%77", "x": "%78", "y": "%79", - "z": "%7A", "{": "%7B", "|": "%7C", "}": "%7D", "~": "%7E", "`": "%80", "": "%81", "‚": "%82", - "ƒ": "%83", "„": "%84", "…": "%85", "†": "%86", "‡": "%87", "ˆ": "%88", "‰": "%89", "Š": "%8A", - "‹": "%8B", "Œ": "%8C", "Ž": "%8E", "‘": "%91", "’": "%92", "“": "%93", "”": "%94", "•": "%95", - "–": "%96", "—": "%97", "˜": "%98", "™": "%99", "š": "%9A", "›": "%9B", "œ": "%9C", "ž": "%9E", - "Ÿ": "%9F", "¡": "%A1", "¢": "%A2", "£": "%A3", "¤": "%A4", "¥": "%A5", "¦": "%A6", "§": "%A7", - "¨": "%A8", "©": "%A9", "ª": "%AA", "«": "%AB", "¬": "%AC", "­": "%AD", "®": "%AE", "¯": "%AF", - "°": "%B0", "±": "%B1", "²": "%B2", "³": "%B3", "´": "%B4", "µ": "%B5", "¶": "%B6", "·": "%B7", - "¸": "%B8", "¹": "%B9", "º": "%BA", "»": "%BB", "¼": "%BC", "½": "%BD", "¾": "%BE", "¿": "%BF", - "À": "%C0", "Á": "%C1", "Â": "%C2", "Ã": "%C3", "Ä": "%C4", "Å": "%C5", "Æ": "%C6", "Ç": "%C7", - "È": "%C8", "É": "%C9", "Ê": "%CA", "Ë": "%CB", "Ì": "%CC", "Í": "%CD", "Î": "%CE", "Ï": "%CF", - "Ð": "%D0", "Ñ": "%D1", "Ò": "%D2", "Ó": "%D3", "Ô": "%D4", "Õ": "%D5", "Ö": "%D6", "×": "%D7", - "Ø": "%D8", "Ù": "%D9", "Ú": "%DA", "Û": "%DB", "Ü": "%DC", "Ý": "%DD", "Þ": "%DE", "ß": "%DF", - "à": "%E0", "á": "%E1", "â": "%E2", "ã": "%E3", "ä": "%E4", "å": "%E5", "æ": "%E6", "ç": "%E7", - "è": "%E8", "é": "%E9", "ê": "%EA", "ë": "%EB", "ì": "%EC", "í": "%ED", "î": "%EE", "ï": "%EF", - "ð": "%F0", "ñ": "%F1", "ò": "%F2", "ó": "%F3", "ô": "%F4", "õ": "%F5", "ö": "%F6", "÷": "%F7", - "ø": "%F8", "ù": "%F9", "ú": "%FA", "û": "%FB", "ü": "%FC", "ý": "%FD", "þ": "%FE", "ÿ": "%FF" - } - retval = "" - if isinstance(payload, unicode): - payload = str(payload) - for char in payload: - if char not in safe: - try: - retval += encodings[char] - except KeyError: - retval += char - else: - retval += char - return retval diff --git a/lib/attacks/xss_scan/__init__.py b/lib/attacks/xss_scan/__init__.py index d9bd4e1..b8ac7e1 100644 --- a/lib/attacks/xss_scan/__init__.py +++ b/lib/attacks/xss_scan/__init__.py @@ -9,8 +9,8 @@ import importlib import requests -from lib.errors import InvalidTamperProvided -from lib.settings import ( +from lib.core.errors import InvalidTamperProvided +from lib.core.settings import ( logger, set_color, DEFAULT_USER_AGENT, @@ -18,11 +18,11 @@ from lib.settings import ( DBMS_ERRORS, create_tree, prompt, - shutdown + shutdown, ) -def list_tamper_scripts(path="{}/lib/attacks/tamper_scripts"): +def list_tamper_scripts(path="{}/lib/tamper_scripts"): retval = set() exclude = ["__init__.py", ".pyc"] for item in os.listdir(path.format(os.getcwd())): @@ -35,8 +35,8 @@ def list_tamper_scripts(path="{}/lib/attacks/tamper_scripts"): def __tamper_payload(payload, tamper_type, warning=True, **kwargs): acceptable = list_tamper_scripts() - tamper_name = "lib.attacks.tamper_scripts.{}_encode" if tamper_type in acceptable: + tamper_name = "lib.tamper_scripts.{}_encode" tamper_script = importlib.import_module(tamper_name.format(tamper_type)) return tamper_script.tamper(payload, warning=warning) else: @@ -70,12 +70,20 @@ def create_urls(url, payload_list, tamper=None): return tf_name -def find_xss_script(url, query=4, fragment=5): +def find_xss_script(url, **kwargs): data = urlparse.urlparse(url) - if data[fragment] is not "" or None: - return "{}{}".format(data[query], data[fragment]) + payload_parser = {"path": 2, "query": 4, "fragment": 5} + if data[payload_parser["fragment"]] is not "" or None: + retval = "{}{}".format( + data[payload_parser["query"]], data[payload_parser["fragment"]] + ) else: - return data[query] + retval = data[payload_parser["query"]] + + # just double checking... + if retval == "" or None: + retval = data[payload_parser["path"]] + return retval def scan_xss(url, agent=None, proxy=None): diff --git a/lib/errors.py b/lib/errors.py deleted file mode 100644 index bd8b81c..0000000 --- a/lib/errors.py +++ /dev/null @@ -1,19 +0,0 @@ -class InvalidProxyType(Exception): pass - - -class ApiConnectionError(Exception): pass - - -class ApplicationNotFound(Exception): pass - - -class SqlmapFailedStart(Exception): pass - - -class SpiderTestFailure(Exception): pass - - -class InvalidInputProvided(Exception): pass - - -class InvalidTamperProvided(Exception): pass \ No newline at end of file diff --git a/lib/settings.py b/lib/settings.py deleted file mode 100644 index 0a5fc7a..0000000 --- a/lib/settings.py +++ /dev/null @@ -1,414 +0,0 @@ -import os -import re -import sys -import time -import glob -import logging -import random -import difflib -import itertools -import multiprocessing - -import whichcraft - -import lib.errors -import bin.unzip_gecko - -try: - raw_input # Python 2 -except NameError: - raw_input = input # Python 3 - -# clone link -CLONE = "https://github.com/ekultek/zeus-scanner.git" -# current version -VERSION = "1.0.34.98ac" -# colors to output depending on the version -VERSION_TYPE_COLORS = {"dev": 33, "stable": 92, "other": 30} -# version string formatting -if VERSION.count(".") == 1: - VERSION_STRING = "\033[92mv{}\033[0m(\033[{}m\033[1mstable\033[0m)".format(VERSION, VERSION_TYPE_COLORS["stable"]) -elif VERSION.count(".") <= 2: - VERSION_STRING = "\033[92mv{}\033[0m(\033[{}m\033[1mdev\033[0m)".format(VERSION, VERSION_TYPE_COLORS["dev"]) -else: - VERSION_STRING = "\033[92mv{}\033[0m(\033[{}m\033[1mrevision\033[0m)".format(VERSION, VERSION_TYPE_COLORS["other"]) -# zeus-scanners saying -SAYING = "Advanced Dork Searching..." -# sexy banner -BANNER = """\033[36m - __ __________ __ - / / \____ /____ __ __ ______ \ \ - / / ______ / // __ \| | \/ ___/ ______ \ \ - \ \ /_____/ / /\ ___/| | /\___ \ /_____/ / / - \_\ /_______ \___ >____//____ > /_/ - \/ \/ \/ {} -\t{}\n\t\t{}\033[0m""".format(VERSION_STRING, CLONE, SAYING) -# default user agent if another one isn't given -DEFAULT_USER_AGENT = "Zeus-Scanner(v{})::Python->v{}.{}".format( - VERSION, sys.version_info[0], sys.version_info[1] -) -# regex to find GET params in a URL, IE php?id= -URL_QUERY_REGEX = re.compile(r"(.*)[?|#](.*){1}\=(.*)") -# regex to recognize a URL -URL_REGEX = re.compile(r"((https?):((//)|(\\\\))+([\w\d:#@%/;$()~_?\+-=\\\.&](#!)?)*)") -# URL's that are extracted from Google's ban URL -EXTRACTED_URL_LOG = "{}/log/extracted-url-log".format(os.getcwd()) -# log path for the URL's that are found -URL_LOG_PATH = "{}/log/url-log".format(os.getcwd()) -# log path for port scans -PORT_SCAN_LOG_PATH = "{}/log/scanner-log".format(os.getcwd()) -# blackwidow log path -SPIDER_LOG_PATH = "{}/log/blackwidow-log".format(os.getcwd()) -# the current log file being used -CURRENT_LOG_FILE_PATH = "{}/log".format(os.getcwd()) -# nmap's manual page for their options -NMAP_MAN_PAGE_URL = "https://nmap.org/book/man-briefoptions.html" -# sqlmap's manual page for their options -SQLMAP_MAN_PAGE_URL = "https://github.com/sqlmapproject/sqlmap/wiki/Usage" -# holder for sqlmap API ID hashes, makes it so that they are all unique -ALREADY_USED = set() -# search engines that the application can use -AUTHORIZED_SEARCH_ENGINES = { - "aol": "http://aol.com", - "bing": "http://bing.com", - "duckduckgo": "http://duckduckgo.com", - "google": "http://google.com" -} -SPIDER_EXT_EXCLUDE = ( - "3ds", "3g2", "3gp", "7z", "DS_Store", - "a", "aac", "adp", "ai", "aif", "aiff", - "apk", "ar", "asf", "au", "avi", "bak", - "bin", "bk", "bmp", "btif", "bz2", "cab", - "caf", "cgm", "cmx", "cpio", "cr2", "dat", - "deb", "djvu", "dll", "dmg", "dmp", "dng", - "doc", "docx", "dot", "dotx", "dra", "dsk", - "dts", "dtshd", "dvb", "dwg", "dxf", "ear", - "ecelp4800", "ecelp7470", "ecelp9600", "egg", - "eol", "eot", "epub", "exe", "f4v", "fbs", "fh", - "fla", "flac", "fli", "flv", "fpx", "fst", "fvt", - "g3", "gif", "gz", "h261", "h263", "h264", "ico", - "ief", "image", "img", "ipa", "iso", "jar", "jpeg", - "jpg", "jpgv", "jpm", "jxr", "ktx", "lvp", "lz", - "lzma", "lzo", "m3u", "m4a", "m4v", "mar", "mdi", - "mid", "mj2", "mka", "mkv", "mmr", "mng", "mov", - "movie", "mp3", "mp4", "mp4a", "mpeg", "mpg", - "mpga", "mxu", "nef", "npx", "o", "oga", "ogg", - "ogv", "otf", "pbm", "pcx", "pdf", "pea", "pgm", - "pic", "png", "pnm", "ppm", "pps", "ppt", "pptx", - "ps", "psd", "pya", "pyc", "pyo", "pyv", "qt", "rar", - "ras", "raw", "rgb", "rip", "rlc", "rz", "s3m", "s7z", - "scm", "scpt", "sgi", "shar", "sil", "smv", "so", "sub", - "swf", "tar", "tbz2", "tga", "tgz", "tif", "tiff", "tlz", - "ts", "ttf", "uvh", "uvi", "uvm", "uvp", "uvs", "uvu", - "viv", "vob", "war", "wav", "wax", "wbmp", "wdp", "weba", - "webm", "webp", "whl", "wm", "wma", "wmv", "wmx", "woff", - "woff2", "wvx", "xbm", "xif", "xls", "xlsx", "xlt", "xm", - "xpi", "xpm", "xwd", "xz", "z", "zip", "zipx" -) -DBMS_ERRORS = { # regular expressions used for DBMS recognition based on error message response - "MySQL": (r"SQL syntax.*MySQL", r"Warning.*mysql_.*", r"valid MySQL result", r"MySqlClient\."), - "PostgreSQL": (r"PostgreSQL.*ERROR", r"Warning.*\Wpg_.*", r"valid PostgreSQL result", r"Npgsql\."), - "Microsoft SQL Server": (r"Driver.* SQL[\-\_\ ]*Server", r"OLE DB.* SQL Server", - r"(\W|\A)SQL Server.*Driver", r"Warning.*mssql_.*", - r"(\W|\A)SQL Server.*[0-9a-fA-F]{8}", - r"(?s)Exception.*\WSystem\.Data\.SqlClient\.", r"(?s)Exception.*\WRoadhouse\.Cms\."), - "Microsoft Access": (r"Microsoft Access Driver", r"JET Database Engine", r"Access Database Engine"), - "Oracle": (r"\bORA-[0-9][0-9][0-9][0-9]", r"Oracle error", r"Oracle.*Driver", - r"Warning.*\Woci_.*", r"Warning.*\Wora_.*"), - "IBM DB2": (r"CLI Driver.*DB2", r"DB2 SQL error", r"\bdb2_\w+\("), - "SQLite": (r"SQLite/JDBCDriver", r"SQLite.Exception", - r"System.Data.SQLite.SQLiteException", r"Warning.*sqlite_.*", - r"Warning.*SQLite3::", r"\[SQLITE_ERROR\]"), - "Sybase": (r"(?i)Warning.*sybase.*", r"Sybase message", r"Sybase.*Server message.*"), -} - - -# this has to be the first function so that I can use it in the logger settings below -def create_log_name(log_path="{}/log", filename="zeus-log-{}.log"): - """ - create the current log file name by figuring out how many files are there - """ - if not os.path.exists(log_path.format(os.getcwd())): - os.mkdir(log_path.format(os.getcwd())) - find_file_amount = len(os.listdir(log_path.format(os.getcwd()))) - full_log_path = "{}/{}".format(log_path.format(os.getcwd()), filename.format(find_file_amount + 1)) - return full_log_path - -# console logger and file logger settings -logger = logging.getLogger("zeus-log") -logger.setLevel(logging.DEBUG) -file_handler = logging.FileHandler( - filename=create_log_name(), mode="a+" -) -file_handler.setLevel(logging.DEBUG) -console_handler = logging.StreamHandler() -console_handler.setLevel(logging.DEBUG) -file_format = logging.Formatter( - '%(asctime)s;%(name)s;%(levelname)s;%(message)s' -) -console_format = logging.Formatter( - "[%(asctime)s %(levelname)s] %(message)s", "%H:%M:%S" -) -file_handler.setFormatter(file_format) -console_handler.setFormatter(console_format) -logger.addHandler(console_handler) -logger.addHandler(file_handler) - - -def create_dir(dirpath): - """ - create a directory if it doesn't exist - """ - if not os.path.exists(dirpath): - os.mkdir(dirpath) - - -def set_color(org_string, level=None): - """ - set the console log color, this will kinda mess with the file log but whatever - """ - color_levels = { - 10: "\033[36m{}\033[0m", # DEBUG - 20: "\033[32m{}\033[0m", # INFO *default - 30: "\033[33m{}\033[0m", # WARNING - 40: "\033[31m{}\033[0m", # ERROR - 50: "\033[7;31;31m{}\033[0m" # FATAL/CRITICAL/EXCEPTION - } - if level is None: - return color_levels[20].format(org_string) - else: - return color_levels[int(level)].format(org_string) - - -def get_proxy_type(proxy_string): - """ - get the type of proxy that is being used or output possible proxy types you're trying to use - """ - acceptable = ("http", "https", "socks5", "socks4") - prox_list = proxy_string.split("://") - if prox_list[0] not in acceptable: - raise lib.errors.InvalidProxyType( - "{} is not a valid proxy type, you might be looking for " - "{}..".format(prox_list[0], difflib.get_close_matches(prox_list[0], acceptable)) - ) - else: - return prox_list[0], prox_list[-1] - - -def proxy_string_to_dict(proxy_string): - """ - send the proxy string to a dict -> http://127.0.0.1:8080 -> {'http': '127.0.0.1:8080'} - """ - if proxy_string is None: - return None - proxy_data = get_proxy_type(proxy_string) - retval = {proxy_data[0]: proxy_data[1]} - return retval - - -def start_up(): - """ - start the program and display the time it was started - """ - print( - "\n\n[*] starting up at {}..\n\n".format(time.strftime("%H:%M:%S")) - ) - - -def shutdown(): - """ - shut down the program and the time it stopped - """ - print( - "\n\n[*] shutting down at {}..\n\n".format(time.strftime("%H:%M:%S")) - ) - exit(0) - - -def setup(verbose=False): - """ - setup the application if it has not been setup yet - """ - if verbose: - logger.debug(set_color( - "checking if the application has been run before...", level=10 - )) - bin.unzip_gecko.main(verbose=verbose) - - -def get_latest_log_file(log_path): - """ - get the latest log file being used from the given path - """ - file_list = glob.glob(log_path + "/*") - try: - latest = max(file_list, key=os.path.getctime) - return latest - except ValueError: - return None - - -def replace_http(url): - """ - replace the http in the url so we can get the IP address - """ - - def __remove_queries(data): - """ - delete the queries from the URL - """ - return data.split("/")[0] - try: - url_list = url.split("//") - new_url = url_list[1] - return __remove_queries(new_url) - except IndexError: - return url - - -def grab_random_agent(agent_path="{}/etc/agents.txt", verbose=False): - """ - grab a random user agent from the agent file - """ - if verbose: - logger.debug(set_color( - "grabbing random user-agent from '{}'...".format(agent_path.format(os.getcwd())), level=10 - )) - with open(agent_path.format(os.getcwd())) as agents: - retval = random.choice(agents.readlines()) - return retval.strip() - - -def prompt(question, opts=None): - """ - ask a question - """ - if opts is not None: - options = '/'.join(opts) - return raw_input( - "[{} {}] {}[{}]: ".format( - time.strftime("%H:%M:%S"), - "PROMPT", question, options - ) - ) - else: - return raw_input( - "[{} {}] {} ".format( - time.strftime("%H:%M:%S"), "PROMPT", question - ) - ) - - -def worker(filename, item): - """ - worker for multiprocessing - """ - if item in filename or filename == item or filename is item: - return filename - - -def find_application(to_find, default_search_path="/", proc_num=25, given_search_path=None, verbose=False): - """ - find an application on the users system if it is not in their PATH or no path is given - """ - retval = set() - if whichcraft.which(to_find) is None: - logger.error(set_color( - "{} not in your PATH, what kind of hacker are you?! " - "defaulting to root search, this can take awhile...".format(to_find), level=40 - )) - - if verbose: - logger.debug(set_color( - "starting {} processes to search for '{}' starting at '{}'...".format( - proc_num, to_find, default_search_path if given_search_path is None else given_search_path - ), level=10 - )) - pool = multiprocessing.Pool(proc_num) - walker = os.walk(default_search_path) - file_data_gen = itertools.chain.from_iterable( - (os.path.join(root, f) for f in files) - for root, sub, files in walker - ) - results = pool.map(worker, file_data_gen) - for data in results: - if data is not None: - retval.add(data) - if len(retval) == 0: - raise lib.errors.ApplicationNotFound( - "unable to find '{}' on your system, install it first...".format(to_find) - ) - else: - return list(retval) - else: - return whichcraft.which(to_find) - - -def get_random_dork(filename="{}/etc/dorks.txt"): - """ - grab a random dork from the file - """ - with open(filename.format(os.getcwd())) as dorks: - return random.choice(dorks.readlines()) - - -def update_zeus(): - can_update = True if ".git" in os.listdir(os.getcwd()) else False - if can_update: - return os.system("git pull origin master") - else: - logger.fatal(set_color( - "no git repository found in directory, unable to update automatically..." - )) - - -def create_tree(start, conns, down="|", over="-", sep="-" * 40): - print("{}\nStarting URL: {}\n\nConnections:".format(sep, start)) - for con in conns: - print( - "{}{}{}".format( - down, over, con - ) - ) - print(sep) - - -def get_true_url(url): - data = url.split("/") - return "{}//{}".format(data[0], data[2]) - - -def fix_log_file(logfile=get_latest_log_file(CURRENT_LOG_FILE_PATH)): - retval = "" - escape_seq_regex = re.compile("\033\[\d+[*m]") - with open(logfile, "r+") as to_fix: - for line in to_fix.readlines(): - retval += escape_seq_regex.sub("", line) - open(logfile, "w").close() - with open(logfile, "a+") as fixed: - for line in retval.split("\n"): - fixed.write(line + "\n") - - -def write_to_log_file(data_to_write, path, filename): - create_dir(path.format(os.getcwd())) - full_file_path = "{}/{}".format( - path.format(os.getcwd()), filename.format(len(os.listdir(path.format( - os.getcwd() - ))) + 1) - ) - with open(full_file_path, "a+") as log: - if isinstance(data_to_write, list): - for item in data_to_write: - item = item.strip() - log.write(str(item) + "\n") - elif isinstance(data_to_write, (tuple, set)): - for item in list(data_to_write): - item = item.strip() - log.write(str(item) + "\n") - else: - log.write(data_to_write + "\n") - logger.info(set_color( - "successfully wrote found items to '{}'...".format(full_file_path) - )) - return full_file_path diff --git a/var/auto_issue/github.py b/var/auto_issue/github.py index 5b68dea..ec08471 100644 --- a/var/auto_issue/github.py +++ b/var/auto_issue/github.py @@ -9,7 +9,7 @@ import platform from base64 import b64decode -from lib.settings import ( +from lib.core.settings import ( logger, set_color, get_latest_log_file, diff --git a/var/blackwidow/__init__.py b/var/blackwidow/__init__.py index 0f072e9..2fccdd2 100644 --- a/var/blackwidow/__init__.py +++ b/var/blackwidow/__init__.py @@ -2,8 +2,8 @@ import os import requests -import lib.settings -import lib.errors +import lib.core.errors +import lib.core.settings class Blackwidow(object): @@ -15,7 +15,7 @@ class Blackwidow(object): def __init__(self, url, user_agent=None, proxy=None): self.url = url self.proxy = proxy or None - self.user_agent = user_agent or lib.settings.DEFAULT_USER_AGENT + self.user_agent = user_agent or lib.core.settings.DEFAULT_USER_AGENT @staticmethod def get_url_ext(url): @@ -24,7 +24,7 @@ class Blackwidow(object): """ try: data = url.split(".") - return data[-1] in lib.settings.SPIDER_EXT_EXCLUDE + return data[-1] in lib.core.settings.SPIDER_EXT_EXCLUDE except Exception: pass @@ -36,13 +36,13 @@ class Blackwidow(object): attempt = requests.get(self.url, params={"user-agent": self.user_agent}, proxies=self.proxy) if attempt.status_code == 200: return "ok" - raise lib.errors.SpiderTestFailure( + raise lib.core.errors.SpiderTestFailure( "failed to connect to '{}', received status code: {}".format( self.url, attempt.status_code ) ) except Exception as e: - lib.settings.logger.exception(lib.settings.set_color( + lib.core.settings.logger.exception(lib.core.settings.set_color( "failed to connect to '{}' received error '{}'...".format( self.url, e ) @@ -56,9 +56,9 @@ class Blackwidow(object): while True: req = requests.get(given_url, params={"user-agent": self.user_agent}, proxies=self.proxy) html_page = req.content - found_links = lib.settings.URL_REGEX.findall(html_page) + found_links = lib.core.settings.URL_REGEX.findall(html_page) for link in list(found_links): - if lib.settings.URL_QUERY_REGEX.match(link[0]) and not Blackwidow.get_url_ext(link[0]): + if lib.core.settings.URL_QUERY_REGEX.match(link[0]) and not Blackwidow.get_url_ext(link[0]): unique_links.add(link) break return list(unique_links) @@ -68,20 +68,20 @@ def blackwidow_main(url, proxy=None, agent=None, verbose=False): """ scrape a given URL for all available links """ - lib.settings.create_dir("{}/{}".format(os.getcwd(), "log/blackwidow-log")) - lib.settings.logger.info(lib.settings.set_color( + lib.core.settings.create_dir("{}/{}".format(os.getcwd(), "log/blackwidow-log")) + lib.core.settings.logger.info(lib.core.settings.set_color( "starting blackwidow on '{}'...".format(url) )) crawler = Blackwidow(url, user_agent=agent, proxy=proxy) if verbose: - lib.settings.logger.debug(lib.settings.set_color( + lib.core.settings.logger.debug(lib.core.settings.set_color( "testing connection to the URL...", level=10 )) crawler.test_connection() if verbose: - lib.settings.logger.debug(lib.settings.set_color( + lib.core.settings.logger.debug(lib.core.settings.set_color( "connection satisfied, continuing process...", level=10 )) found = crawler.scrape_page_for_links(url) to_use = [data[0] for data in found] - lib.settings.write_to_log_file(to_use, path=lib.settings.SPIDER_LOG_PATH, filename="blackwidow-log-{}.log") + lib.core.settings.write_to_log_file(to_use, path=lib.core.settings.SPIDER_LOG_PATH, filename="blackwidow-log-{}.log") diff --git a/var/google_search/search.py b/var/google_search/search.py index 057dbcd..cebca5e 100644 --- a/var/google_search/search.py +++ b/var/google_search/search.py @@ -19,7 +19,7 @@ from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.proxy import * from var.auto_issue.github import request_issue_creation -from lib.settings import ( +from lib.core.settings import ( logger, set_color, proxy_string_to_dict, diff --git a/zeus.py b/zeus.py index 92a5c2a..b1f0ae8 100755 --- a/zeus.py +++ b/zeus.py @@ -1,10 +1,11 @@ #!/usr/bin/env python -import os -import time import optparse -import subprocess +import os import random +import subprocess +import time + try: import http.client as http_client # Python 3 except ImportError: @@ -13,7 +14,7 @@ except ImportError: from var import blackwidow from var.google_search import search from var.auto_issue.github import request_issue_creation -from lib.errors import InvalidInputProvided +from lib.core.errors import InvalidInputProvided from lib.attacks.admin_panel_finder import main from lib.attacks.xss_scan import main_xss from lib.attacks.nmap_scan.nmap_opts import NMAP_API_OPTS @@ -24,7 +25,7 @@ from lib.attacks import ( sqlmap_scan, intel_me ) -from lib.settings import ( +from lib.core.settings import ( setup, BANNER, start_up,