From 1df61579011aae75f794871e501559498faae7cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20GASCOU=20=28Podalirius=29?= Date: Fri, 3 Mar 2023 12:27:07 +0100 Subject: [PATCH] Release 3.1, Added 403 bypass (#20) Co-authored-by: Edra <69597623+Edr4@users.noreply.github.com> --- Makefile | 1 + apachetomcatscanner/Reporter.py | 27 ++++++++-------- apachetomcatscanner/__main__.py | 2 +- apachetomcatscanner/utils/scan.py | 54 +++++++++++++++++++------------ setup.py | 2 +- 5 files changed, 50 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index 8af8759..faeb28a 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ install: build python3 setup.py install build: + python3 -m pip uninstall apachetomcatscanner --yes python3 setup.py sdist bdist_wheel upload: build diff --git a/apachetomcatscanner/Reporter.py b/apachetomcatscanner/Reporter.py index 7d958f2..2c727cd 100644 --- a/apachetomcatscanner/Reporter.py +++ b/apachetomcatscanner/Reporter.py @@ -23,14 +23,12 @@ def __init__(self, config, vulns_db): self.vulns_db = vulns_db self._new_results = [] - def report_result(self, computer_ip, computer_port, tomcat_version, manager_accessible, credentials_found): + def report_result(self, computer_ip, computer_port, result, credentials_found): computer_port = str(computer_port) - finding = {} + finding = result.copy() finding["computer_ip"] = computer_ip finding["computer_port"] = computer_port - finding["tomcat_version"] = tomcat_version - finding["manager_accessible"] = manager_accessible finding["credentials_found"] = credentials_found if computer_ip not in self.data.keys(): @@ -43,7 +41,6 @@ def report_result(self, computer_ip, computer_port, tomcat_version, manager_acce def print_new_results(self): try: for finding in self._new_results: - # List of cves cve_str = "" if self.config.list_cves_mode == True: @@ -51,26 +48,28 @@ def print_new_results(self): if len(cve_list) != 0: cve_str = "CVEs: %s" % ', '.join(cve_list) - # credentials_str = "username:%s\npassword:%s" % (credentials_found[0][1]["username"], credentials_found[0][1]["password"]) - if finding["manager_accessible"]: - print("[>] [Apache Tomcat/\x1b[1;95m%s\x1b[0m] on \x1b[1;93m%s\x1b[0m:\x1b[1;93m%s\x1b[0m (manager:\x1b[1;92maccessible\x1b[0m) %s\x1b[0m " % ( - finding["tomcat_version"], + print("[>] [Apache Tomcat/\x1b[1;95m%s\x1b[0m] on \x1b[1;93m%s\x1b[0m:\x1b[1;93m%s\x1b[0m (manager: \x1b[1;92maccessible\x1b[0m) on %s\x1b[0m " % ( + finding["version"], finding["computer_ip"], finding["computer_port"], - cve_str + finding["manager_url"] ) ) + if len(finding["credentials_found"]) != 0: for statuscode, creds in finding["credentials_found"]: if len(creds["description"]) != 0: - print(" | Valid user: \x1b[1;92m%s\x1b[0m | password:\x1b[1;92m%s\x1b[0m | \x1b[94m%s\x1b[0m" % (creds["username"], creds["password"], creds["description"])) + print(" | Valid user: \x1b[1;92m%s\x1b[0m | password: \x1b[1;92m%s\x1b[0m | \x1b[94m%s\x1b[0m" % (creds["username"], creds["password"], creds["description"])) else: - print(" | Valid user: \x1b[1;92m%s\x1b[0m | password:\x1b[1;92m%s\x1b[0m" % (creds["username"], creds["password"])) + print(" | Valid user: \x1b[1;92m%s\x1b[0m | password: \x1b[1;92m%s\x1b[0m" % (creds["username"], creds["password"])) + + if len(cve_str) != 0: + print(" | %s" % cve_str) else: - print("[>] [Apache Tomcat/\x1b[1;95m%s\x1b[0m] on \x1b[1;93m%s\x1b[0m:\x1b[1;93m%s\x1b[0m (manager:\x1b[1;91mnot accessible\x1b[0m) %s\x1b[0m " % ( - finding["tomcat_version"], + print("[>] [Apache Tomcat/\x1b[1;95m%s\x1b[0m] on \x1b[1;93m%s\x1b[0m:\x1b[1;93m%s\x1b[0m (manager: \x1b[1;91mnot accessible\x1b[0m) %s\x1b[0m " % ( + finding["version"], finding["computer_ip"], finding["computer_port"], cve_str diff --git a/apachetomcatscanner/__main__.py b/apachetomcatscanner/__main__.py index c7831ae..a5f5058 100755 --- a/apachetomcatscanner/__main__.py +++ b/apachetomcatscanner/__main__.py @@ -19,7 +19,7 @@ from concurrent.futures import ThreadPoolExecutor -VERSION = "3.0" +VERSION = "3.1" banner = """Apache Tomcat Scanner v%s - by @podalirius_\n""" % VERSION diff --git a/apachetomcatscanner/utils/scan.py b/apachetomcatscanner/utils/scan.py index b5104a4..a3f7a7b 100644 --- a/apachetomcatscanner/utils/scan.py +++ b/apachetomcatscanner/utils/scan.py @@ -6,11 +6,10 @@ import base64 import datetime -import re import time +import traceback +import re from apachetomcatscanner.utils.network import is_port_open, is_http_accessible - - import requests # Disable warnings of insecure connection for invalid certificates requests.packages.urllib3.disable_warnings() @@ -22,8 +21,7 @@ pass -def is_tomcat_manager_accessible(target, port, config, scheme="http"): - path = "/manager/html" +def is_tomcat_manager_accessible(target, port, path, config, scheme="http"): url = "%s://%s:%d%s" % (scheme, target, port, path) try: r = requests.get( @@ -86,43 +84,58 @@ def try_default_credentials(target, port, config, scheme="http"): def scan_worker(target, port, reporter, config, monitor_data): + manager_access_paths = [ + "/manager/html", + "/..;/manager/html" + ] + try: result = {"target": target} if is_port_open(target, port): for scheme in config.get_request_available_schemes(): if is_http_accessible(target, port, config, scheme): + result["scheme"] = scheme result["version"] = get_version_from_malformed_http_request(target, port, config, scheme) if result["version"] is not None: config.debug("Found version %s" % result["version"]) - result["manager_accessible"] = is_tomcat_manager_accessible(target, port, config, scheme) + result["manager_accessible"] = False + result["manager_path"] = "" + for urlpath in manager_access_paths: + if is_tomcat_manager_accessible(target, port, urlpath, config, scheme): + result["manager_accessible"] = True + result["manager_path"] = urlpath + result["manager_url"] = "%s://%s:%d%s" % (scheme, target, port, urlpath) + break - credentials_found = [] if result["manager_accessible"]: - config.debug("Manager is accessible") - # Test for default credentials - credentials_found = try_default_credentials(target, port, config, scheme) - - reporter.report_result( - target, - port, - result["version"], - result["manager_accessible"], - credentials_found - ) + credentials_found = [] + if result["manager_accessible"]: + config.debug("Manager is accessible") + # Test for default credentials + credentials_found = try_default_credentials(target, port, config, scheme) + + reporter.report_result( + target, + port, + result, + credentials_found + ) monitor_data["lock"].acquire() monitor_data["actions_performed"] = monitor_data["actions_performed"] + 1 - # print("Updated for port %d" % port) + monitor_data["lock"].release() except Exception as e: if config.debug_mode: print("[Error in %s] %s" % (__name__, e)) + traceback.print_exc() def monitor_thread(reporter, config, monitor_data): + time.sleep(1) last_check, monitoring = 0, True while monitoring: new_check = monitor_data["actions_performed"] @@ -145,4 +158,5 @@ def monitor_thread(reporter, config, monitor_data): if len(reporter._new_results) != 0: reporter.print_new_results() - print() \ No newline at end of file + print() + diff --git a/setup.py b/setup.py index 9a912a4..f5810d9 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ setuptools.setup( name="apachetomcatscanner", - version="3.0", + version="3.1", description="", url="https://github.com/p0dalirius/ApacheTomcatScanner", author="Podalirius",