From cadc40b81a083c5ee9a06e95e88e73a7b8e299dd Mon Sep 17 00:00:00 2001 From: ekultek Date: Tue, 19 Dec 2017 10:01:04 -0600 Subject: [PATCH] patches an issue where the XSS scan fails if it does not have a protocol (issue #314) --- etc/checksum/md5sum.md5 | 8 +++---- lib/attacks/xss_scan/__init__.py | 39 +++++++++++++++++++------------- lib/core/parse.py | 13 +++++++++++ lib/core/settings.py | 4 +++- zeus.py | 2 +- 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/etc/checksum/md5sum.md5 b/etc/checksum/md5sum.md5 index 19f89d4..c245a29 100644 --- a/etc/checksum/md5sum.md5 +++ b/etc/checksum/md5sum.md5 @@ -1,4 +1,4 @@ -1ad9b1b53231b6d64c8055e3162b8851 ./zeus.py +e46c781638861a5651a51a5a71f5d997 ./zeus.py 4b32db388e8acda35570c734d27c950c ./etc/scripts/launch_sqlmap.sh 6ad5f22ec4a6f8324bfb1b01ab6d51ec ./etc/scripts/cleanup.sh 74d7bee13890a9dd279bb857591647ce ./etc/scripts/reinstall.sh @@ -99,7 +99,7 @@ d41d8cd98f00b204e9800998ecf8427e ./lib/attacks/__init__.py d41d8cd98f00b204e9800998ecf8427e ./lib/attacks/whois_lookup/__init__.py c5b69617f040fef1d5930948905aa8d0 ./lib/attacks/whois_lookup/whois.py 4fd96bb3002e949687d7ae863ee87264 ./lib/attacks/admin_panel_finder/__init__.py -352b3740b54ef13b77ec57e9e68372b5 ./lib/attacks/xss_scan/__init__.py +2017e69c3420c9e240fccb310f086da7 ./lib/attacks/xss_scan/__init__.py 40ba04fb18dcbb81cb42376a825c238f ./lib/attacks/nmap_scan/__init__.py 216999fa0e84866d5c1d96d5676034e4 ./lib/attacks/nmap_scan/nmap_opts.py 0114ebe3d45612ef143f2777f027374c ./lib/header_check/__init__.py @@ -107,8 +107,8 @@ c5b69617f040fef1d5930948905aa8d0 ./lib/attacks/whois_lookup/whois.py de4254c5e40f7aa4fb81e0608f758a2c ./lib/core/decorators.py 4433353fb5c55578391d8b4006191ee8 ./lib/core/errors.py d41d8cd98f00b204e9800998ecf8427e ./lib/core/__init__.py -19f98bf3830e61f2ca78549cb747a724 ./lib/core/settings.py -28b94f316ad528cdfba77694b4e52c81 ./lib/core/parse.py +bbf88de258c6cb72b74d2ef6bb50a6f6 ./lib/core/settings.py +a6608451e6d4df7f39d8a3c720d57f3d ./lib/core/parse.py d41d8cd98f00b204e9800998ecf8427e ./var/__init__.py d41d8cd98f00b204e9800998ecf8427e ./var/auto_issue/__init__.py 8e9092a4783a2d82f49c2dd824f11950 ./var/auto_issue/github.py diff --git a/lib/attacks/xss_scan/__init__.py b/lib/attacks/xss_scan/__init__.py index 6199996..f096f65 100644 --- a/lib/attacks/xss_scan/__init__.py +++ b/lib/attacks/xss_scan/__init__.py @@ -29,6 +29,19 @@ def list_tamper_scripts(path="{}/lib/tamper_scripts"): return retval +def assign_protocol(url, force=False): + auto_assign = ("http://{}", "https://{}") + url_verification = re.compile(r"http(s)?", re.I) + + if url_verification.search(url) is None: + if not force: + return auto_assign[0].format(url) + else: + return auto_assign[1].format(url) + else: + return url + + def __tamper_payload(payload, tamper_type, warning=True, **kwargs): """ add the tamper to the payload from the given tamper type @@ -58,7 +71,7 @@ def __load_payloads(filename="{}/etc/text_files/xss_payloads.txt"): with open(filename.format(os.getcwd())) as payloads: return payloads.readlines() -def create_urls(url, payload_list, tamper=None, verbose=False): +def create_urls(url, payload_list, tamper=None, verbose=False, force=False): """ create the tampered URL's, write them to a temporary file and read them from there """ @@ -78,7 +91,7 @@ def create_urls(url, payload_list, tamper=None, verbose=False): " | ".join(list_tamper_scripts()), level=40 ) )) - loaded_url = "{}{}\n".format(url.strip(), payload.strip()) + loaded_url = "{}{}\n".format(assign_protocol(url.strip(), force=force), payload.strip()) tmp.write(loaded_url) return tf_name @@ -109,15 +122,6 @@ def scan_xss(url, agent=None, proxy=None): be tampered or encoded if the site is not vulnerable """ - auto_assign = "http://{}" - url_verification = re.compile(r"http(s)?", re.I) - - if url_verification.search(url) is None: - lib.core.settings.logger.warning(lib.core.settings.set_color( - "protocol missing from URL, automatically assigning protocol", level=30 - )) - url = auto_assign.format(url) - try: _, status, html_data, _ = lib.core.common.get_page(url, agent=agent, proxy=proxy) query = find_xss_script(url) @@ -140,6 +144,7 @@ def main_xss(start_url, proxy=None, agent=None, **kwargs): tamper = kwargs.get("tamper", None) verbose = kwargs.get("verbose", False) batch = kwargs.get("batch", False) + force = kwargs.get("force_ssl", False) question_msg = ( "it appears that heuristic tests have shown this URL may not be a good " @@ -174,7 +179,7 @@ def main_xss(start_url, proxy=None, agent=None, **kwargs): lib.core.settings.logger.info(lib.core.settings.set_color( "payloads will be written to a temporary file and read from there" )) - filename = create_urls(start_url, payloads, tamper=tamper, verbose=verbose) + filename = create_urls(start_url, payloads, tamper=tamper, verbose=verbose, force=force) lib.core.settings.logger.info(lib.core.settings.set_color( "loaded URL's have been saved to '{}'".format(filename), level=25 )) @@ -225,11 +230,13 @@ def main_xss(start_url, proxy=None, agent=None, **kwargs): except ( requests.exceptions.ConnectionError, requests.exceptions.TooManyRedirects, - requests.exceptions.ReadTimeout + requests.exceptions.ReadTimeout, + requests.exceptions.InvalidURL ): - lib.core.settings.logger.error(lib.core.settings.set_color( - "payload '{}' caused a connection error, assuming no good and continuing".format(payload), level=40 - )) + if not payload == "": + lib.core.settings.logger.error(lib.core.settings.set_color( + "payload '{}' caused a connection error, assuming no good and continuing".format(payload), level=40 + )) if len(success) != 0: lib.core.settings.logger.info(lib.core.settings.set_color( diff --git a/lib/core/parse.py b/lib/core/parse.py index 95aaa2c..54399f0 100644 --- a/lib/core/parse.py +++ b/lib/core/parse.py @@ -45,6 +45,8 @@ class ZeusParser(OptionParser): mandatory.add_option("-f", "--url-file", dest="fileToEnumerate", metavar="FILE-PATH", help="Run an attack on URL's in a given file") + # being worked on + # TODO:/ mandatory.add_option("-u", "--url", dest="singleTargetRecon", metavar="URL", help=SUPPRESS_HELP) @@ -70,6 +72,8 @@ class ZeusParser(OptionParser): attacks.add_option("-c", "--clickjacking", dest="performClickjackingScan", action="store_true", help="Perform a clickjacking scan on a provided URL") + # being worked on + # TODO:/ attacks.add_option("-g", "--github-search", dest="searchGithub", action="store_true", help=SUPPRESS_HELP) @@ -99,6 +103,8 @@ class ZeusParser(OptionParser): attacks.add_option("--tamper", dest="tamperXssPayloads", metavar="TAMPER-SCRIPT", help="Send the XSS payloads through tampering before sending to the target") + # being worked on + # TODO:/ attacks.add_option("--thread", dest="threadPanels", action="store_true", help=SUPPRESS_HELP) @@ -144,6 +150,11 @@ class ZeusParser(OptionParser): help="Attempt to identify if the target is protected by some kind of " "WAF/IDS/IPS") + # being worked on + # TODO:/ + search_items.add_option("--force-ssl", dest="forceSSL", action="store_true", + help=SUPPRESS_HELP) + search_items.add_option("--identify-plugins", dest="identifyPlugin", action="store_true", help="Attempt to identify what plugins the target is using") @@ -185,6 +196,8 @@ class ZeusParser(OptionParser): misc.add_option("--version", dest="showCurrentVersion", action="store_true", help="Show the current version and exit") + # being worked on + # TODO:/ misc.add_option("-T", "--x-threads", dest="amountOfThreads", metavar="THREAD-AMOUNT", type=int, help=SUPPRESS_HELP) diff --git a/lib/core/settings.py b/lib/core/settings.py index 4397a56..d08edf1 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -45,7 +45,7 @@ CLONE = "https://github.com/ekultek/zeus-scanner.git" ISSUE_LINK = "https://github.com/ekultek/zeus-scanner/issues" # current version -VERSION = "1.4.11.{}".format(PATCH_ID) +VERSION = "1.4.12.{}".format(PATCH_ID) # colors to output depending on the version VERSION_TYPE_COLORS = {"dev": 33, "stable": 92, "other": 30} @@ -943,6 +943,7 @@ def run_attacks(url, **kwargs): agent = kwargs.get("agent", None) conf_file = kwargs.get("conf_file", None) threads = kwargs.get("threads", None) + force_ssl = kwargs.get("ssl", False) if threads > MAX_THREADS: threads = check_thread_num(threads, batch=batch) @@ -1005,6 +1006,7 @@ def run_attacks(url, **kwargs): main_xss( url, verbose=verbose, proxy=proxy, agent=agent, tamper=tamper_script, batch=batch, + force_ssl=force_ssl ) elif whois: from lib.attacks.whois_lookup.whois import whois_lookup_main diff --git a/zeus.py b/zeus.py index 57c36df..8cc57c4 100755 --- a/zeus.py +++ b/zeus.py @@ -138,7 +138,7 @@ if __name__ == "__main__": show_all=opt.showAllConnections, do_threading=opt.threadPanels, tamper_script=opt.tamperXssPayloads, timeout=opt.controlTimeout, proxy=proxy_to_use, agent=agent_to_use, conf_file=opt.sqlmapConfigFile, - threads=opt.amountOfThreads + threads=opt.amountOfThreads, force_ssl=opt.forceSSL ) print("\n") else: